1

基本的な質問がたくさん頭に浮かびます。それらをクリアする必要があります。

ステートメント1:コンパイラーは、人間が読み取れるコードをオブジェクトコードに変換し、それらはリンカーによってマシンコード(実行可能)に変換されます。

私はここにいますか?

ウィキペディアでは、

Object files are produced by an assembler, compiler, or other language
translator, and used as input to the linker.

質問1:アセンブラはアセンブリ言語コード(MOV A, B ADD C)を機械語に変換します。C ++のような高級言語の場合、それは上記のリンカーによって生成されます。したがって、アセンブラはどこにも使用されません。では、上記のようにオブジェクトファイルを作成するにはどうすればよいでしょうか。

中間コードは、コードをさまざまなアーキテクチャで実行するために生成されます。

質問2: * .class(バイトコード)ファイルはJavaコンパイラオブジェクトファイルによって作成されていますか?はいの場合、それらを実行するJVMは一種のリンカーであると言えますか(ただし、実行可能ファイルは作成されません)。

質問3: Turbo C++でC++プログラムをコンパイルすると、オブジェクトファイルである*.objファイルが取得されます。それらを使用して、他のアーキテクチャで実行可能ファイルを生成できますか?

4

2 に答える 2

2

質問1:はい、アセンブラ(as、gas、nasm、masm)はアセンブリ命令をオブジェクトコードにコンパイルします。高水準言語(H)の場合、コンパイラーはHを別の言語にコンパイルします(たとえば、GHC、Glorious HaskellコンパイラーはCを生成できますが、C--も生成でき、生成する試み(?)がありました。 Java)、または中間ステップ(または言語C-またはコア)を介してオブジェクトコードに変換します。

中間コードは、さまざまな理由で生成できます。1. Javaからの.classファイルなどの移植性、Pascalのpコード2.コードの最適化を容易にするため

質問2:.classファイルはJavaコンパイラーで生成できますが、Scalaも.classファイルを生成し、AspectJ(アスペクト指向フレーバー)も.classファイルを生成します。.classファイルは、Java仮想マシンが必要であるという意味でオブジェクトファイルではありません(また、unixリンカーldは.classファイルを.oファイルにリンクしません)。元のJVMは.classファイルのインタープリターですが、Javaをオンザフライでコンパイルすることもできます。

質問3:Turbo C ++ .objファイル(64ビットIntelでコンパイル)は、コンパイラーが別のアーキテクチャー用にクロスコンパイルするオプションを持っていない限り、Z80マシンでは満足できません。したがって、TurboC++の場合はオブジェクトファイルの目的です。プラットフォーム間の移植性ではありません。

于 2012-11-06T09:57:52.157 に答える
2

オブジェクトファイルは、リンクされる「マシンコード」(.text)、初期化されたデータ、およびシンボルのコレクションです。

有効なオブジェクトファイルには、バイトコードなどのデータのみを含めることができます。

リンカは、多数のオブジェクトを仮想アドレス空間にマップし、外部シンボルが属するアドレスを解決するプログラムです。これにより、関数printfなどを呼び出すときにインターフェイスを知るだけでよいため、プログラムの段階的な開発が可能になります。リンカは、リンク段階でマシンコード内にprintfの実際のアドレスを挿入します。これは、再配置テーブルを使用して行われます。

これは、質問3に部分的に答えます。別のアーキテクチャで作成されたオブジェクトファイルを直接使用することはできません。インターフェース方法は必ずしもバイナリ互換ではありません。また、objファイルの形式は異なる場合があります。しかし、本当に努力すれば、TurboCでコンパイルされたオブジェクトをVisualCから呼び出すことができるラッパー(ほとんどの場合、アセンブリ内)を作成できます。命令セットやメモリモデルなどが完全に異なる場合でも、働き。これらの種類のアプローチは、たとえばビデオ再生フレームワークを作成するときに常に使用されます。ビデオ再生フレームワークは、.dllでのみ提供されるレガシービデオデコーダーを呼び出すことができます。

リンクは、OSが実行可能ファイルをディスクからメモリにロードするとき、またはプログラムが「ダイナミックライブラリ」にリンクされているときにも部分的に発生します。このような場合、「printf」への呼び出しを多く挿入できますが、リンカは「スタブ」への呼び出しのみを行います。スタブは、一度呼び出されると、OSから適切なライブラリをロードし、それ自体をライブラリ関数に置き換えます。

ステートメント#1は十分に正しくありません。コンパイラとアセンブラは、人間が読めるコードを機械語に変換しますが、一部のコンパイラは、解釈される(および/または「ジャストインタイム」コンパイルされる)中間言語を生成します。この最後の段階では、コンパイルは実際にはそれが何をすべきかを意味します-マシンコードにコンパイルします。

Gccには、アセンブラーとリンカーが含まれています。シンボリックマシンコードであるアセンブラ(hw.s)でコンパイルint main() { printf("HelloW\n");}し、いくつかの行を挿入または置換し、オブジェクトコードに再コンパイルして、最後にリンクすることができますgcc -S hw.cgcc -c hw.sgcc -o hw.exe hw.o

于 2012-11-06T09:36:57.753 に答える