2つの間に違いはありますか?あたりとしてウルマンの本、コンパイラは、言語別の(通常は低レベル)に一つの言語に変換し、そのアセンブラはありません。この2つはどう違うのですか?
2つの間に違いはありますか?あたりとしてウルマンの本、コンパイラは、言語別の(通常は低レベル)に一つの言語に変換し、そのアセンブラはありません。この2つはどう違うのですか?
回答:
アセンブラーは、アセンブリコードをマシンコードに変換します。翻訳は機械的なものであり、1つの方法でのみ実行できます。対照的に、コンパイラーは、関連するプログラミング言語をコンパイルする際により多くの自由があります。たとえば、最適化することができ、最適化しないコンパイラーでも異なるコードを生成します。また、コンパイラは、「フロントエンド」(プログラミング言語に対応)と「バックエンド」(コンピューターアーキテクチャに対応)を分離する方法で作成できますが、アセンブラーでは2つは常に同じです。
一番下の行は、アセンブラよりもコンパイラを書く方が楽しいということです。アセンブリ言語は通常、解析と型チェックがほとんど自明になるように設計されており、多くのテーブル駆動ジェネレーターを使用する傾向があります(「addのオペコードは01110です」、「ロード命令の場合、宛先オペランドレジスタはビット17から21で指定されます」 ")。通常、アセンブラの最も興味深い部分は、シンボリックラベルを数値に解決する部分です。
ただし、ほとんどのアセンブラーは、少量の算術演算(たとえば、小さな定数で記号ラベルを加算する)を実行でき、ほとんどのアセンブラーはマクロ処理機能を持っているか、統合されています。(ほとんどのUnixシステムでは、実際にマクロ機能は、適切なアセンブラーに渡す前にアセンブリーに対してCプリプロセッサーを実行することにより提供されます。)
MIPSアセンブラーはそれ以上の一歩を踏み出さなければならず、いくつかの興味深いコード生成の決定を行い、少量の最適化を行いました。 たとえば、MIPSマシン言語では、さまざまな定数を読み込むためにさまざまなコードシーケンスが必要であるため、アセンブラは定数を作成した後にコードシーケンスを選択する必要がありました。さらに、MIPSマシンコードには遅延スロットの概念がありましたが、これらを抽象化し、より「通常の」抽象アセンブリ言語をコンパイラに提示するのはアセンブラの責任でした。そのため、MIPSアセンブラーはローカル命令のスケジューリングを行う必要があります。
区別は、ノーマン・ラムジーの作品、特に彼のC-- portableアセンブリ言語によってさらに曖昧になります。(関連論文は、ラムジーとペイトンジョーンズ、「例外の複数の実装をサポートする単一の中間言語」、Prog。Lang。Impl。and Dsgn。、(PLDI-21):285–298、2000です。)そして最後に、また、David WalkerとGreg Morrisettの型付きアセンブリ言語であり、メモリの安全性を保証できるアセンブラを備えています。
ここで少し簡単に答えると、現実はもっと複雑です。私は、アセンブラー(A)とコンパイラー(C)の違いが他のものの中にあることを期待しています。
アセンブリ言語を「低レベル」、コンパイラが理解するソース言語を「高レベル」と呼ぶ傾向があります(これはかなり単純化されていますが、それでもなお)。
アセンブリ言語では、たとえば次のように追加操作を実行できます。
高水準言語では、次のように記述できます。
そして、これは、多くの状況に応じて、1つの命令または数百の命令になる可能性があります。1つは、コンパイラが命令を作成するCPUです。
ご覧のとおり、アセンブリのソース言語はほとんどの場合:(A)1行のソースコードが1行のCPUオペコードを提供し、ターゲットのCPUに大きく依存します。高レベル言語(C)コンパイラーがこれらすべての詳細を処理します。1行のソースコードがゼロ、1つまたは複数のCPUオペコードになり、コンパイラーがCPUの機能の詳細を処理します。
今日のコンパイラは、多くの場合、いくつかの異なる段階で構成されています。それらは、フロントエンド/バックエンドまたは他のものと呼ばれるbeeingと名付けられます。私は通常、それらを4つの段階と考えています。
優れたコンパイラーを書くことは非常に熟練した職業です。おもちゃの言語コンパイラーを作ることは午後にアマチュア(または少し長い)で行うことができます。