包括的な説明は、おそらくこのフォーラムの範囲を超えています。テキスト全体が主題に専念しています。ただし、単純化したレベルでは、このように見ることができます。
コンパイラはコードをメモリに配置しません。それ自体にメモリ領域全体があると想定しています。コンパイラは、オブジェクト ファイル内のシンボルが通常オフセット 0 で始まるオブジェクト ファイルを生成します。
リンカーは、オブジェクト ファイルをまとめて、シンボルをリンクされたオブジェクト内の新しいオフセット位置にリンクし、実行可能ファイル形式を生成する役割を果たします。
リンカはコードをメモリに配置しません。コードとデータを、通常.text
は実行可能コードの指示や.data
、グローバル変数や文字列定数などのラベルが付けられたセクションにパッケージ化します。(そして、さまざまな目的のための他のセクションもあります) リンカは、シンボルを再配置するオペレーティング システム ローダーにヒントを提供する場合がありますが、ローダーは強制する必要はありません。
実行可能ファイルを解析し、コードとデータをメモリ内のどこに配置するかを決定するのは、オペレーティング システムのローダーです。その場所は、オペレーティング システムに完全に依存します。通常、スタックはプログラムの命令やデータよりも上位のメモリ領域に配置され、下に向かって成長します。
各プログラムは、それ自体にアドレス空間全体があるという前提でコンパイル/リンクされます。ここで仮想メモリの出番です。仮想メモリはプログラムに対して完全に透過的であり、オペレーティング システムによって完全に管理されます。
仮想メモリの範囲は通常、アドレス 0 から、プラットフォームでサポートされている最大アドレス (無限ではありません) までです。この仮想アドレス空間は、オペレーティング システムによってカーネル アドレス空間とユーザー アドレス空間に分割されます。架空の 32 ビット OS では、上のアドレス0x80000000
はオペレーティング システム用に予約されており、下のアドレスはプログラムで使用するためのものです。プログラムがこのパーティションより上のメモリにアクセスしようとすると、中断されます。
オペレーティング システムは、スタックがアドレス指定可能な最上位のユーザー メモリから開始し、プログラム コードがはるかに低いアドレスにあると判断する場合があります。
通常、ヒープの場所は、プログラムをビルドしたランタイム ライブラリによって管理されます。プログラムコードとデータの後に利用可能な次のアドレスから始まる可能性があります。