ウィキペディアから:
このセグメントのサイズは、プログラムがコンパイルまたはアセンブルされる前にプログラマが配置した値によって決定され、実行時に変更されません。
では、セグメントのサイズを実際に決定するのは誰でしょうか? OS?さらに、いつ計算されますか?「プログラムがコンパイルまたはアセンブルされる前」は、前処理段階で行われたことを意味しますか?
伝統的にコンパイルされた言語の場合、大まかに言えば、答えはリンカです。
各オブジェクト ファイルには、さまざまなセグメントのサイズ (および配置など) に関する情報が含まれています。リンカーがオブジェクト ファイルをつなぎ合わせて実行可能ファイルを形成するとき、一致するセグメントを整列を尊重する方法で集約します。パーツの順序、つまり潜在的に最終セグメントのサイズは、リンカー次第です。
配置を維持するためにパディングを追加する必要がある場合、セグメントのサイズが変わることがあります。
解釈または JIT コンパイルされたプログラムには、実際にはセグメントがないことに注意してください。
あなたが引用したウィキペディアのテキストは間違っているか、誤解を招くものです。アセンブリまたはコンパイルの前にデータ セグメントが存在しません。
データ セグメントは、次の方法で構築されます。
アセンブリでは、プログラマはデータ セクションを明示的に宣言し、そこに配置する値を定義できます。一部のアセンブラは、プログラマが特定の機能を使用したときにデータ セクションにデータを自動的に追加する機能も提供します。たとえば、アセンブリ ラインldr r7, =345
はアセンブラに 345 をデータ セクションに入れ、そのアドレスをldr
命令に入力するように要求する場合があります。
高水準言語では、コンパイラはコードを処理するときに必要なデータを構築します。これには、プログラマによって直接記述された定数が含まれる場合があります (たとえば、高レベル コードをアセンブリに変換するプロセスで作成された345
inまたは値。(たとえば、 を記述した場合、コンパイラは添字を 112 として計算し、それをデータセクション)。x = 345;
i = 35; y = x[i*3+7];
リンカーは、処理するオブジェクト モジュールのデータ セクションを 1 つのデータ セグメントに結合します。サイズは、結合されたデータのサイズです。(FORTRAN 共通セグメントなどの一部のデータ セクションは共有される場合があるため、複数のオブジェクト モジュールからのデータが連結されるのではなく重複します。)
ライブラリが動的に読み込まれる場合、それらのデータ セグメントはリンク時に結合できず、ローダーによって個別に管理される必要があります。そのため、実行中のプログラムには複数のデータ セグメントが含まれる場合があります。
「プログラムがコンパイルされる前に..」の部分は、どの変数および/または定数が存在する必要があるかを参照する必要があります。
データ セクション/セグメントのサイズは、リンカーによって計算されます。これは、このタイプの情報が記録されるヘッダーを含む、出力ファイルを実際に構築する役割を担うコンパイル/アセンブリ プロセスの一部です。
サイズの計算は、参加しているオブジェクト モジュールのデータ セクションに含まれる内容に基づいて行われます。