私自身 (アセンブラと逆アセンブラ) をいくつか書きましたが、x86 から始めるつもりはありません。x86またはその他の命令セットを知っている場合は、別の命令セットの構文をすぐに(夕方/午後)ピックアップして学習できます。少なくともライオンズはそれを共有します. アセンブラー (または逆アセンブラー) を作成する行為は、確実に命令セットを迅速に教えてくれます。また、そのレベルでマイクロコードを調べたことのない、その命令セットの多くの経験豊富なアセンブリ プログラマーよりも、その命令セットについてよく理解できます。msp430、pdp11、thumb (thumb2 拡張機能ではない) (または mips または openrisc) はすべて、開始するのに適した場所であり、多くの指示がなく、過度に複雑ではないなどです。
最初に逆アセンブラをお勧めします。それには、arm、thumb、mips、openrisc などの固定長の命令セットを使用します。そうでない場合は、少なくとも逆アセンブラを使用します (間違いなく、既にアセンブラ、リンカ、および逆アセンブラー) と鉛筆と紙を使用して、機械コードとアセンブリ、特に分岐の関係を理解すると、オフセットが追加されたときにプログラムカウンターが命令の 1 つまたは 2 つ先にあるなどの癖が通常 1 つまたは複数あり、別のビットを得ることができます。バイトではなく命令全体で測定する場合があります。
Cプログラムでテキストを力ずくで解析して命令を読むのはとても簡単です。より難しい作業ですが、おそらく教育として、bison/flex を使用し、そのプログラミング言語を学習して、これらのツールが (さらに極端なブルート フォース) パーサーを作成できるようにすることです。パーサーは、コードにインターフェイスして、どこで何が見つかったかを伝えます。
アセンブラ自体は非常に単純です。ASCII を読み取り、マシン コードにビットを設定するだけです。ブランチやその他の PC 相対命令は、完全に解決するためにソース/テーブルを複数回通過する可能性があるため、少し面倒です。
mov r0,r1
mov r2 ,#1
アセンブラは行 (キャリッジ リターン 0xD またはライン フィード 0xA に続くバイトとして定義されます) のテキストの解析を開始し、空白以外の何かに到達するまで空白 (スペースとタブ) を破棄し、それから strncmp を既知のニーモニック。ヒットした場合は、その命令の可能な組み合わせを解析します。上記の単純なケースでは、mov が空白を非空白にスキップした後、おそらく最初に見つけたのはレジスタ、次にオプションの空白、次にコンマ。空白とコンマを削除し、それを文字列のテーブルと比較するか、単に解析します。そのレジスターが完了したら、コンマが見つかった場所を通り過ぎて、それが別のレジスターまたは即時のいずれかであるとしましょう。即時の場合は # 記号が必要であり、レジスタの場合は小文字または大文字で始まる必要があります ' r'. そのレジスタまたは即時を解析した後、その行にあるべきではない行に他に何もないことを確認してください。この命令のマシン コードをビルドするか、少なくともできるだけ多くのマシン コードをビルドし、次の行に進みます。面倒かもしれませんが、ASCII を解析するのは難しくありません...
少なくとも、作成時にマシンコード/データを蓄積するテーブル/配列に加えて、命令が未完了であるとマークするための何らかの方法、PC 相対命令が将来のパスで完了する必要があります。また、見つけたラベルを収集するテーブル/配列と、見つかったマシンコードテーブルのアドレス/オフセットも必要になります。宛先/ソースとして命令で使用されるラベルと、部分的に完了した命令を保持するテーブル/配列内のオフセットと同様に、それらが使用されます。最初のパスの後、ラベル定義のアドレス/オフセットを使用して問題の命令までの距離を計算し、作成を完了するまで、すべてのラベル定義をソースまたは宛先として使用されるラベルと一致させるまで、これらのテーブルに戻ります。その命令のマシンコード。
次のステップは、許可したい場合は、複数のソース ファイルを許可することです。アセンブラーによって解決されないラベルを用意する必要があるため、出力にプレースホルダーを残し、最長のジャンプ/分岐命令のフレーバーを作成する必要があります。次に、作成/使用するために選択した出力ファイル形式があります。リンカがあります。これはほとんど単純ですが、最終的な PC 相対命令のマシンコードを記入することを覚えておく必要があります。アセンブラの場合よりも難しくありません。自体。
アセンブラを書くことは、必ずしもプログラミング言語を作成してからそのためのコンパイラを書くことに関連しているとは限らないことに注意してください。別のことであり、別の問題です。実際、新しいプログラミング言語を作成したい場合は、既存の命令セットに既存のアセンブラーを使用するだけです。もちろん必須ではありませんが、ほとんどの教育やチュートリアルでは、プログラミング言語に bison/flex アプローチを使用します。また、コンパイラ クラスを開始するための大学のコースの講義ノートやリソースが数多くあります。言語の機能を追加するスクリプト。ミドルエンドとバックエンドは、フロントエンドよりも大きな課題です。このトピックに関する書籍は多数あり、オンライン リソースも多数あります。