14

少し調べてみましたが、正解が見つかりませんでしたので、ご意見をいただければ幸いです。

アセンブリ言語(ARM)を学びたいのですが、これにはRaspberry Piが適していますか?

私が見る限り、LEDフラッシュの作成などを行うための穏やかなチュートリアルがいくつかあるように思われるので、初心者の観点からはそれほど怖くはなく、実際にはとても楽しいようです。

Raspberry Piから始めて、逆アセンブラーを使用して知識を蓄積した場合、私は良い道を進んでいますか、それとも間違った足で始めていますか?

コメントしてくださってありがとうございます。

4

1 に答える 1

22

はいといいえ。これが最初のアセンブリ言語である場合、ARMは最初から良い言語です(x86は悪い言語です)(他にも良い言語があります)。最初に命令セットシミュレータを使用して学習することをお勧めします。これにより、何が起こっているのかをよりよく把握でき、成功の可能性が高くなります(欲求不満のために諦める可能性が低くなります)。ツールで足を濡らしたり、ベアメタルプログラムを構築したりしたら、ラズベリーパイは悪いプラットフォームではありません。周辺機器は、ドキュメントが不十分ですが、(他の同様のプラットフォームと比較して)非常に簡単に使用できますが、ドキュメントを補うのに十分なコミュニティと例があります。ラズベリーパイは、ARMの観点からはブリック不可能と見なすことができます。あなたの最初の点滅するLEDプログラムを作ろうとしてボードをブリックすることは非常にイライラすることがあります。

私は、新しい(私にとって)命令セットを学ぶ方法として逆アセンブラを書くことを大いに信じています。ARM命令セットは固定ワード長(32ビット)であり、分解が非常に簡単です。純粋なサム命令は16ビットに固定されており、分解がさらに簡単です。ただし、thumbにはthumb2拡張機能があり、それが難しくなるので、最初はそれらを避けます。固定ワード長の命令セットを使用すると、バイナリイメージを安全にウォークスルーし、最初から最後まで分解することができます。データは奇妙に見えますが、指示は正しい場所にあります。可変ワード長では、最初から始めて線形に逆アセンブルすることはできません(thumb2拡張を使用すると、可変命令長を意味します)、3バイトの命令、次に1バイトのデータ、次に別のバイトの命令があります。直線的に、そのバイトのデータは命令として分解され、マルチバイト命令としてデコードされた場合は、同期がとれなくなります。可変命令長バイナリを分解する唯一の適切な方法は、実行順序でコードのすべてのパスをたどり、そこから可能なことを分解することです(すべての可能なコードパスをエミュレートしないと、すべての命令をデータから区別できない場合があります) 。可変命令長の逆アセンブルは間違いなく高度なトピックです。最初にアセンブリ言語である程度の強みを身に付けてください。おそらく、逆アセンブラに取り組む前に、可変ワード長命令セットの命令セットシミュレータを作成することもできます(基本的に、バイナリを完全にデコードするのではなく、部分的にデコードして、可変ワード長命令セットの逆アセンブラを作成する必要があります。

thumbulatorとamber_samplesの両方のアプローチは固定命令長であるため、asmとマシンコードとasmの関係を簡単に確認できます。また、コードが実行されていることを確認し、コードが雑草になって死んだ理由を理解します(これは、ラズベリーパイやその他のハードウェアでは見られません)。

単純な点滅するLEDの例を介して、次にビデオピクセルに手を差し伸べる、カンブライド大学の例があります。ディスカッションフォーラムのベアメタルセクションに例へのリンクを投稿した他の個人と同様に。「アセンブリ言語でこれを行うにはどうすればよいか」を理解するために、小さなC関数を記述し、(最適化を使用して)コンパイルしてから逆アセンブルします。私は特に、printf()のようなコードではなく、a+bのようなコードについて話しています。プロセッサフ​​ァミリに固有の(共通の)アセンブリ言語であるインストルメンテーションセットの学習があります。次に、システムコールまたはライブラリコールを学習した後で議論します。「文字列を印刷するにはどうすればよいですか」というようなものには、ハードウェアの学習と システム(ROMモニター/デバッガー)またはライブラリー(Cライブラリーまたは他の高級言語の関数呼び出しとそれらのライブラリーを利用するための規則。それ自体が他の多くのライブラリーを呼び出し、多くのジャンクがリンクされている可能性があります)。したがって、Cを使用して「アセンブリ言語」を学習するということは、ライブラリ呼び出し、memcpy、printfなどがないことを意味します。ただし、システム呼び出しとライブラリ呼び出しを使用する場合は、そのシステムまたはリンクで実行するasmコードを記述する必要があります。それ自体がシステムに依存している可能性のある呼び出しを使用します。高水準言語のCやPythonなどの学習について考えてみてください。言語の学習、変数の宣言、加算、減算、xorなどの演算子の学習があります。ポインターや配列の使用方法など。ある時点でCライブラリを学習します。呼び出し、printf()、strcpy()、mallocなど。YMMV、

システムの一部としてasmを学習することを選択した場合は、Linuxにとどまり、いくつかの単純なC関数を作成し、コンパイルと逆アセンブルを行い、コンパイラーの呼び出し規約を学習し、armリファレンス資料を使用して手順を確認することをお勧めします。それらはコンパイラによって作成されます。asmを使用してその関数を最初から作成し、Cプログラムにリンクしてから、その関数を変更する方法を学びます。これは、私が上で説明したものとは完全に異なるアプローチです。失敗の可能性を持って作られましたが、間違いなく例による学習アプローチです。

于 2012-12-01T18:49:56.907 に答える