生のマシンコード命令を出力するアセンブラーファイルを取得するコンパイラーを作成しようとしています。
コンパイラの書き方に関するチュートリアルをたくさん見つけましたが、すべての段階がアセンブラのニーモニックに関連しているかどうか疑問に思っています。たとえば、単純化された段階ごとの形式のアセンブラーを考えると、字句解析はまったく必要ですか、それとも必要ですが、より単純な形式では必要ですか?
生のマシンコード命令を出力するアセンブラーファイルを取得するコンパイラーを作成しようとしています。
コンパイラの書き方に関するチュートリアルをたくさん見つけましたが、すべての段階がアセンブラのニーモニックに関連しているかどうか疑問に思っています。たとえば、単純化された段階ごとの形式のアセンブラーを考えると、字句解析はまったく必要ですか、それとも必要ですが、より単純な形式では必要ですか?
字句解析器は引き続き必要です。テキストを個々のトークン (単語、数字、句読点など) に分割するものが必要です。かなり単純化されたものですが、パーサーも必要です。やっぱり文法はあります。
コンパイラのほぼすべての段階をアセンブラに適用できると思いますが、もちろん、何を適用するかによって異なります。1 対 1 のマッピングを作成する場合は、エラーをチェックするための構文解析と、アセンブリへの指定子のテキストを処理するためのレクサーおよび/またはパーサーが必要.data
です。また、即時の定数を可能な限り最小のサイズにすることで適用できるサイズの「最適化」もあります。もちろん、徹底的に分析して命令の並べ替えと融合を行うこともできます。また、静的分析ステージで無効な (不正な) シーケンスをチェックすることもできます (LOCK CMPXCHG EDX,EDX
構文的には正しいが無効なアセンブリ iirc の例になります)。
私が見ているように、必要なのは字句解析だけであり、アセンブリのフラットな構造のためにパーサーの必要性が少なくなります。
最初に、無効な命令/オペランドがないかどうかを確認し、次に使用されているすべての変数が宣言されているかどうかを確認します。ファイルが有効なプログラムであることを確認したら、コメントを削除し、変数とプロシージャをアドレスに置き換えます (現時点ではアドレスがわからないため、変換中に「その場で」ラベルにアドレスを割り当てる必要があります)。最後に、バイナリ コードで実際の変換を行います。
すべての命令に独自の行があると仮定すると、はるかに簡単になります。現在の行がラベルの場合、それ以降のすべての参照を現在のアドレスに置き換えます。そうでない場合は、すべてのスペースを削除して、2 つの「単語」の間に 1 つ残します (命令とオペランド)。今処理命令は冗談です。;)