コンパイラとアセンブラの間に実際の違いはありますか?


14

2つの間に違いはありますか?あたりとしてウルマンの本、コンパイラは、言語別の(通常は低レベル)に一つの言語に変換し、そのアセンブラはありません。この2つはどう違うのですか?


1
アセンブラ、特定のタスクセットを実行するコンパイラです。用語は実際には多少異なりますが、「コンパイラー」(言語間の翻訳)の基本的な定義が適用されます。
ラファエル

すべてのアセンブラは、ある言語を別の言語に変換するため、(単純な)コンパイラです。すべてのコンパイラがアセンブラーではありません。
user253751

回答:


16

アセンブラーは、アセンブリコードをマシンコードに変換します。翻訳は機械的なものであり、1つの方法でのみ実行できます。対照的に、コンパイラーは、関連するプログラミング言語をコンパイルする際により多くの自由があります。たとえば、最適化することができ、最適化しないコンパイラーでも異なるコードを生成します。また、コンパイラは、「フロントエンド」(プログラミング言語に対応)と「バックエンド」(コンピューターアーキテクチャに対応)を分離する方法で作成できますが、アセンブラーでは2つは常に同じです。


2
なぜ翻訳が一方向にしかできないのですか?つまり、特定のマシンコード(およびターゲットアーキテクチャ)に対して元のasmコードを生成できないということですか?それは私にとって直感的ではないように思えます。特定のマシンコード命令が複数のasm命令にマップできる場合、マシンはどの命令を実行するかをどのように決定するのですか?何か不足していますか?
Utku

2
ATAA

おかげで、ウルマンの本では、コンパイラにフロントエンドとバックエンドがあることもわかりました。私が正しい場合、バックエンドは中間言語での最適化、マシンコードの生成、マシンコードの最適化を実行し、3つのタスクはそれぞれ複数の方法で実行できます。「バックエンド」部分はアセンブラーですか?中間言語はアセンブリ言語ですか?はい、と思いますが、あなたの返信には、アセンブラーが一方向にしか仕事をしていないと書かれています。
ティム

私はそれをここに掲載cs.stackexchange.com/questions/98854/...
ティム・

中間言語は通常、マシンに依存しない言語を指します。
ユヴァルフィルマス

11

一番下の行は、アセンブラよりもコンパイラを書く方が楽しいということです。アセンブリ言語は通常、解析と型チェックがほとんど自明になるように設計されており、多くのテーブル駆動ジェネレーターを使用する傾向があります(「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の型付きアセンブリ言語であり、メモリの安全性を保証できるアセンブラを備えています。


0

ここで少し簡単に答えると、現実はもっと複雑です。私は、アセンブラー(A)とコンパイラー(C)の違いが他のものの中にあることを期待しています。

  1. ソースコードの1行は、1つのCPUオペコードに直接関連しています(A)またはそうでない(C)
  2. 実際のCPU(A)またはマシンに依存しない(C)に大きく依存

アセンブリ言語を「低レベル」、コンパイラが理解するソース言語を「高レベル」と呼ぶ傾向があります(これはかなり単純化されていますが、それでもなお)。

アセンブリ言語では、たとえば次のように追加操作を実行できます。

  • a、bを追加します(1つの特定のCPU用)
  • R5、R6を追加(異なるCPU用)
  • add(A5)、D2(異なるCPU用)

高水準言語では、次のように記述できます。

  • x = y + z;

そして、これは、多くの状況に応じて、1つの命令または数百の命令になる可能性があります。1つは、コンパイラが命令を作成するCPUです。

ご覧のとおり、アセンブリのソース言語はほとんどの場合:(A)1行のソースコードが1行のCPUオペコードを提供し、ターゲットのCPUに大きく依存します。高レベル言語(C)コンパイラーがこれらすべての詳細を処理します。1行のソースコードがゼロ、1つまたは複数のCPUオペコードになり、コンパイラーがCPUの機能の詳細を処理します。

今日のコンパイラは、多くの場合、いくつかの異なる段階で構成されています。それらは、フロントエンド/バックエンドまたは他のものと呼ばれるbeeingと名付けられます。私は通常、それらを4つの段階と考えています。

  1. 最初の段階では、実際のソースコードを読み取り、内部表現を作成します。この段階は実際のソース言語を知っています。
  2. 2番目の段階では、内部表現を見て、いくつかの最適化を行います。最近では、コンパイラは通常、プログラムを高速化し、サイズが大きくなっても気にしないようにします。最適化は内部表現で行われます。興味深いことに、これの一部はいくつかの異なる言語に対して汎用的である可能性があります。
  3. 3番目の段階では、内部表現を使用して、選択したCPUの実際のコードを作成します。このステージには、異なるCPUをターゲットとするいくつかの異なるバージョンが存在する場合があります。実際には、ソースコードを一度書いてから、異なるCPUS向けにコンパイルすることができます。
  4. プログラムを「パッケージング」するための最終準備(この段階はリンカーになる可能性があります)。

優れたコンパイラーを書くことは非常に熟練した職業です。おもちゃの言語コンパイラーを作ることは午後にアマチュア(または少し長い)で行うことができます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.