.o ファイルはオブジェクト ファイルです。これは、最終的なプログラムの中間表現です。
具体的には、通常、.o ファイルにはコンパイル済みのコードが含まれていますが、さまざまなルーチンやデータすべての最終アドレスは含まれていません。
プログラムを実行する前に必要なものの 1 つは、メモリ イメージに似たものです。
例えば。
メインプログラムがあり、それがルーチン A を呼び出すとします。
PROGRAM MAIN
INTEGER X,Y
X = 10
Y = SQUARE(X)
WRITE(*,*) Y
END
次に、SQUARE 関数があります。
FUNCTION SQUARE(N)
SQUARE = N * N
END
は個別にコンパイルされたユニットです。MAIN がコンパイルされると、「SQUARE」がどこにあるのか、どのアドレスにあるのかがわからないことがわかります。そのため、マイクロプロセッサの JUMP SUBROUTINE (JSR) 命令を呼び出すとき、その命令にはどこかへ行く場所があることを知る必要があります。
.o ファイルにはすでに JSR 命令がありますが、実際の値はありません。これは、後でリンクまたはロード フェーズで行われます (アプリケーションによって異なります)。
そのため、MAINS .o ファイルには main のすべてのコードと、解決したい参照のリスト (特に SQUARE) が含まれています。SQUARE は基本的にスタンドアロンであり、参照はありませんが、同時にメモリ内のどこに存在するかについてのアドレスはまだありません。
リンカーはすべての .o ファイルを取り出し、それらを 1 つの exe に結合します。昔は、コンパイルされたコードは文字通りメモリ イメージでした。プログラムは、あるアドレスから開始し、単純に RAM ホールセールにロードされてから実行されます。したがって、このシナリオでは、リンカが 2 つの .o ファイルを取得し、それらを連結して (SQUARE の実際のアドレスを取得するため)、戻って MAIN で SQUARE 参照を見つけ、アドレスを入力することがわかります。
最新のリンカはそこまでは進んでおらず、その最終処理の多くをプログラムが実際にロードされるまで延期します。しかし、コンセプトは似ています。
.o ファイルにコンパイルすることで、再利用可能なロジック ユニットが作成され、実行前にリンクおよびロード プロセスによって結合されます。
もう 1 つの優れた点は、.o ファイルをさまざまな言語から取得できることです。呼び出しメカニズムに互換性がある限り (つまり、関数やプロシージャとの間で引数がどのように渡されるか)、.o にコンパイルされると、ソース言語の関連性は低くなります。たとえば、C コードと FORTRAN コードをリンク、結合できます。
PHP などでは、実行時にすべてのコードが 1 つのイメージに読み込まれるため、プロセスが異なります。FORTRAN の .o ファイルは、PHP のインクルード メカニズムを使用してファイルを結合し、まとまりのある大きな全体にする方法に似ていると考えることができます。