ほとんどの人は、アセンブリの学習が不可欠であり、コンピューターの基礎となる仕組みを知ることが重要であるなどと示唆しています。しかし、私が探しているのは、Assembly を学習する努力を価値あるものにする実用的な提案です。
あなたの提案は何ですか?一般に、アセンブリとポインター/メモリ管理を学習しないことで、私は何を見逃していますか?
アセンブリ言語、ポインター、メモリ管理などの低レベルの事柄を学習することの主な実際的な利点は、高レベルのコードを書いたりレビューしたりするときに、パフォーマンスの問題やその他の落とし穴を本能的または無意識のうちに見つけられるようになることです。
平均的な開発者は、単純なループを作成して、「このコードは一連の整数を繰り返し処理し、それぞれをコンソールに書き込む」と考えるかもしれません。
熟練した開発者は、同じループを作成して、「このコードは一連の整数を繰り返し処理し、ToString メソッドを呼び出すために各要素をボックス化する必要があり、ToString は基数 10 で文字列をフォーマットする必要がありますが、これは自明ではありません。ボックス化された整数とフォーマットされた文字列の両方がすぐにガベージ コレクションの対象となり、参照が残っていないため、このメソッドを初めて実行するときに、JIT を実行する必要があります...」などです。
10回のうち9回は問題ないかもしれません。しかし、10 分の 1 の確率で、熟練した開発者は、平均的な開発者が考えもしないようなコードの問題に気付く可能性があります。
複雑なステートメントが爆発したときに何がうまくいかないかを理解できるように、アセンブリを読むことを学ぶ必要があります。CPUデバッグウィンドウは不思議な場所であってはなりません。
ポインター/メモリ管理は、アセンブリ言語よりも一般的です。C および C++ についても理解する必要があります。これは、C で記述されたコードを維持する必要がある場合に必要になる場合があります。
アセンブリ言語の場合、C コンパイラが生成するアセンブラ コードを読んで、正しく効率的なコードが生成されるかどうかを確認すると便利な場合があります。
新しい言語を学ぶのは素晴らしいことだと思います。それは私の心を開きます。一部の言語は他の言語よりも心を開いています。アセンブラーもその一つだと思います。コールスタックや命令ポインタなどについて考える必要があります。そしてそれはあなたに高級言語をさらに高く評価させるでしょう。学ぶべきもう一つの楽しい言語はPostScriptです。
実用的なことのためにアセンブリを学ぶ必要はないと思います。 ただし、開発者として行っていることの本当のルーツを確実に理解することができます。本質的に、アセンブリプログラミングは、チップのロジックとアーキテクチャを学習するための分野です。私は20年以上アセンブリをプログラミングしていませんが、C#をプログラミングするときに行う選択の種類を示しています。
これは、常に尋ねられる質問の 1 つです。「なぜ何かを知っている必要があるのか」。たぶん、次の一般的な CRUD アプリケーションなどを構築する以外に何かをする仕事を得ることができるでしょう。なんらかのシステム開発を行いたい場合、アセンブリに関する実用的な知識があると非常に役立ちますが、必須ではありません。あなたが「見逃している」ものに関して言えば、コンピューターがどのように機能するかを実際に知っていることを見逃しているのかもしれません。これが望ましいと考える人もいます。そうでない人もいます。プロセッサを構築する人もいます。溝を掘る人もいます。それはすべて個人的な好みの問題です:)
しかし、私が探しているのは、Assemblyを学ぶ努力を価値あるものにするいくつかの実用的な提案です。
アセンブリとは何かを学びます。それの小さな断片を読む(そして理解する)方法を本当に学びましょう:あなたの心の中でそれを歩く/歩む方法。おそらく、デバッガーを使用してその一部をステップ実行します(メモリーとレジスターが変更されていることを確認することを含む)。理想的には、注釈付きのアセンブリを見つけます。
ただし、アセンブリの記述方法をわざわざ学ぶ必要はありません。代わりに、CまたはC ++の記述方法を学ぶことは、ほとんどの実用的な目的にはおそらく「低」です。
ポインタとメモリ管理は、実際にはアセンブリとは異なる問題です。C / C ++を実行する場合は、ポインターとメモリ管理を学習する必要があります。これらは言語の一部であるためです。ただし、(たとえば)Javaだけを一生使用する予定がある場合でも、GCにもかかわらずメモリリークを書き込まないようにするために、メモリ管理について何かを学ぶ必要があります。ポインタは、アトミックタイプとオブジェクト参照の違いにすぎません。コンセプトが必要です。そうしないと、機能しないプログラムを作成します。
アセンブリを学習する実際的な理由:デバッグと最適化。アセンブリを作成しなくても、最近ではパフォーマンスのためにC /C++コードを最適化する必要があるかもしれません。その場合、別の行を書き込む必要がない場合でも、内部ループのアセンブリを読み取ることができる必要があります。
結局のところ、「コンピュータの基本的な動作を知ること」と「アセンブリを学習する努力を価値あるものにする実用的な提案」との区別は誤りだと思います。無知は報われません。コンピュータがどのように機能するかを学ぶことは、努力する価値のある実用的な提案です。
私には予言があります。いつの日か、プログラムの実行が遅すぎて実用的でなくなり、メモリ不足の例外を除いて断続的にクラッシュします。その日、何が起こっているのか、それを修正するためにどこから探し始めるのかわからないというまったくの悲鳴を上げる不安は、興味を持ってあなたのカルマの借金を払い戻すでしょう...
ボンネットの下にあるものを知る必要がある理由について、いくつかの実用的な例があります。このコンテキストで役立つと思われるいくつかの便利なリンクは次のとおりです-
最近の多くのアセンブリ言語は、実際にはかなり高レベルです。
そして、「C」を学べば、ほとんどの学習効果を得るのに十分にアセンブリに近いということは常に真実です。
編集: これについてもう少し考えてみると、Knuth の本の中で、彼は理想化されたアセンブリ言語について説明しています。それを学んだり、それらの本を読んだりすることは、間違いではありません。
私が考えることができるもう 1 つの実用的な理由は、アプリケーション コードをリバース エンジニアリングして、教育目的のみに変更することです。これは、時間制限やシリアル番号などのシェアウェア アプリケーションの保護を回避するためにクラッカーによって広く使用されているためです。
win32Dasm のようなアプリケーションは、実行可能ファイルをアセンブリ コードに変換できます。アセンブリ コードは、hiew のような 16 進エディタで後で変更できます。プログラムの流れがかなり学べます。
実際のレベルでは、80 年代初頭に初めてコーディングを学習したときに、6502 アセンブラーのクラスを受講しました。また、8088 アセンブラもいくつか行いました。それ以来、時折使用されてきましたが、25年間で1、2回以上、本当に穴から抜け出したとは言えません. かなり基本的なレベルで C を理解することは、はるかに役に立ちます。YMMVとそれは確かに背景として役立ちますが、直接的な実用的な利点としては? 本当に限界。
逆に、有用であることが証明されていることの 1 つは、さらに低いレベルのものです。私はクラス オン チップ設計 (NAND ゲートなど) を行い、その一環として、形式的なブール論理をある程度深く教えました。それ以来、これは非常に便利です - ands、ors、nots で何をしているのかを本当に知らないコーダーの数は驚くべきことです :-)
組み立てと併せてコンピューターのアーキテクチャーについて学ぶと、かなり心が開かれると思います。
多くのパフォーマンスの問題を説明するのに役立ちます-たとえば、多くのブランチがあるためパーサーが遅く、パイプラインが非常に簡単にフラッシュされ、ブランチプレディクターはすべてを補うことができません。
また、異なるアーキテクチャには癖があります。誰かが、xor を含む 2 つのレジスタをその場でスワップするアセンブリのトリックについて話しました。それは機能し、順序どおりの実行コア (最新の例は Intel Atom とネットブックの Via C7) ではうまく動作しますが、順不同のコアではそれほどうまくいきません。
それを知っていると、アセンブリで検査することでコンパイルが不十分なコードを検出するのに役立ち、コンパイラオプティマイザの不完全性を回避するために高水準言語でコードを記述できる可能性があります。私はそれらを否定しようとしているわけではありませんが、完全に調整することはできません.
アセンブリを学習することの最大の実際的な利点は、パフォーマンスです。必要に応じて、ほぼ完璧に最適化できます。