「「オブジェクトファイル」とは何ですか?」という質問を受けました。
Wikiを見た後、オブジェクトが含まれていることしかわかりません。
しかし、それらのオブジェクトとは何で、なぜ誰かがそのように呼んだのでしょうか?
「「オブジェクトファイル」とは何ですか?」という質問を受けました。
Wikiを見た後、オブジェクトが含まれていることしかわかりません。
しかし、それらのオブジェクトとは何で、なぜ誰かがそのように呼んだのでしょうか?
オブジェクトファイル(またはオブジェクトコード)は、コンパイラがソースコードから生成したマシンコードファイルです。
実行可能ファイルとの違いは、オブジェクトファイルがリンクされていないため、関数やシンボルなどへの参照がまだ定義されていないことです(これらのメモリアドレスは基本的に空白のままです)。
GCCでCファイルをコンパイルする場合:
gcc -Wall -o test test.c
ここでは、コンパイルとリンクを行っています。したがって、実行可能ファイルには、含まれているシンボル(ライブラリ、ヘッダーなど)のすべてのメモリアドレス参照が含まれています。
しかし、これを行うと:
gcc -Wall -o test.o -c test.c
ファイルを作成してオブジェクト化します。これもマシンコードですが、実行可能ファイルまたはライブラリを作成するにはリンクする必要があります。
たとえば、多数のCファイルを含むプロジェクトがある場合は、それぞれをオブジェクトコードにコンパイルしてから、すべてのオブジェクトファイルをリンクして最終製品を作成します。
例えば:
gcc -Wall -o foo.o -c foo.c // Object file for foo.c
gcc -Wall -o bar.o -c bar.c // Object file for bar.c
gcc -Wall -o main.o -c main.c // Object file for main.c
gcc -Wall -o software foo.o bar.o main.o // Executable (foo + bar + main)
オブジェクトという用語は、ここではリンクされていないマシンコードのシーケンスを表します(基本的に)。オブジェクトファイルにはオブジェクトが含まれています。
あなたは尋ねました:なぜこの呼び出しはそのようになっているのですか?本当に答えられません。「青」が「青」と名付けられたのはなぜですか?; )。
それは、それ以来使用されている用語です...まあ、数十年...
詳細については、GCC Internalsのドキュメントでは、オブジェクトコードを次のように定義しているだけです。
作品の「ソースコード」とは、作品に変更を加えるための好ましい形式の作品を意味します。「オブジェクトコード」とは、非ソース形式の作品を意味します。
歴史的な理由についてはかなり漠然としています...
オブジェクトファイルとは何かを理解していただければ幸いです。言葉はただの言葉なので、なぜそのように呼ばれるのかを知ることよりも重要だと思います...
この名前は、次のことを区別することに関係していると思います。
オブジェクトファイルには次のものが含まれます。
- ヘッダー情報:コードのサイズ、翻訳元のソースファイルの名前、作成日など、ファイルに関する全体的な情報。
- オブジェクトコード:コンパイラまたはアセンブラによって生成されたバイナリ命令とデータ。
- 再配置:リンカがオブジェクトコードのアドレスを変更するときに修正する必要があるオブジェクトコード内の場所のリスト。
- シンボル:このモジュールで定義されているグローバルシンボル、他のモジュールからインポートされるシンボル、またはリンカによって定義されるシンボル。
- デバッグ情報:リンクには必要ないが、デバッガーに使用するオブジェクトコードに関するその他の情報。これには、ソースファイルと行番号の情報、ローカルシンボル、C構造体定義などのオブジェクトコードで使用されるデータ構造体の説明が含まれます。
出典:こちら
オブジェクト ファイルは、ソース (テキスト) ファイルのバイナリ表現です。これは、データの種類を次のように分離するさまざまなセクションのコレクションです。
コンパイラ/環境によって、これらは異なる場合があります。
*nix システムの例:
objdump -d a.out <--- a.cpp をコンパイルした場合
disassembly of section .init:
08048278 <_init>:
8048278: 55 push %ebp
8048279: 89 e5 mov %esp,%ebp
804827b: 83 ec 08 sub $0x8,%esp
804827e: e8 61 00 00 00 call 80482e4 <call_gmon_start>
8048283: e8 b3 00 00 00 call 804833b <frame_dummy>
8048288: e8 9f 01 00 00 call 804842c <__do_global_ctors_aux>
804828d: c9 leave
804828e: c3 ret
Disassembly of section .plt:
08048290 <puts@plt-0x10>:
8048290: ff 35 78 95 04 08 pushl 0x8049578
8048296: ff 25 7c 95 04 08 jmp *0x804957c
804829c: 00 00 add %al,(%eax)
...
080482a0 <puts@plt>:
80482a0: ff 25 80 95 04 08 jmp *0x8049580
80482a6: 68 00 00 00 00 push $0x0
80482ab: e9 e0 ff ff ff jmp 8048290 <_init+0x18>
080482b0 <__libc_start_main@plt>:
80482b0: ff 25 84 95 04 08 jmp *0x8049584
80482b6: 68 08 00 00 00 push $0x8
80482bb: e9 d0 ff ff ff jmp 8048290 <_init+0x18>
Disassembly of section .text:
ここでのさまざまな呼び出しコマンドは、実際の関数を呼び出すためにさまざまなライブラリに関連付けられます。
リンクしたページによると、各シーケンスまたはオブジェクトには通常、ホストマシンがタスクを実行するための指示が含まれており、関連するデータやメタデータ(再配置情報、スタック巻き戻し情報、コメント、プログラムシンボル、デバッグまたはプロファイリング情報など)が付随している可能性があります。 )。
基本的に、オブジェクトファイル内の各オブジェクトは関数であり、リンカが完全なプログラムに含めるための関連情報です。