コンピューティングにおいて、データセグメント(多くの場合.dataと表記される)とは、初期化された静的変数(グローバル変数と静的ローカル変数)を含む、オブジェクトファイルまたはプログラムの対応するアドレス空間の一部を指します。このセグメントのサイズは、プログラムのソースコード内の値のサイズによって決まり、実行時に変更されることはありません。
データセグメントは、実行時に変数の値を変更できるため、読み書き可能です。これは、読み取り専用のデータセグメント(.rodataセグメント(または.rodata)には、変数ではなく静的定数が含まれます。これはコード セグメント(テキスト セグメントとも呼ばれる)とは対照的です。初期化されていないデータ(変数と定数の両方)は、代わりに.bssセグメントにあります。
歴史的に、内部アドレスレジスタのネイティブサイズよりも大きなメモリアドレス空間をサポートするために、初期のCPUはセグメンテーションシステムを実装し、特定の領域へのオフセットとして使用する少数のインデックスを格納していました。Intel 8086ファミリーのCPUは、コードセグメント、データセグメント、スタックセグメント、およびエクストラセグメントの4つのセグメントを提供しました。各セグメントは、実行されるソフトウェアによってメモリ内の特定の位置に配置され、これらのセグメント内のデータを操作するすべての命令は、そのセグメントの開始位置を基準として実行されました。これにより、通常は64KB のメモリ空間にアクセスできる16ビットアドレスレジスタが、1MBのメモリ空間にアクセスできるようになりました 。
メモリ空間を特定のタスクを持つ個別のブロックに分割するというこの考え方は、当時のプログラミング言語にも引き継がれ、現代のプログラミング言語でも広く用いられている。
コンピュータのプログラムメモリは、大きく分けて読み取り専用と読み書き可能な2つのセクションに分類できます。この区分は、初期のシステムがメインプログラムをマスクROM、EPROM、PROM、EEPROMなどの読み取り専用メモリに格納していたことに由来します。システムが複雑化し、プログラムがROMから実行されるのではなく、他のメディアからRAMにロードされるようになると、プログラムメモリの一部は変更すべきではないという考え方が維持されました。これらはプログラムの.textおよび.rodataセグメントとなり、書き込み可能な残りの部分は、特定のタスクのために複数のセグメントに分割されました。
コードセグメント(テキストセグメントとも呼ばれる)には実行可能なコードが含まれており、通常は読み取り専用で固定サイズです。

データセグメントには、初期化された静的変数、つまり定義済みの値を持ち変更可能なグローバル変数とローカル静的変数が含まれます。C言語の例は次のとおりです。
int i = 3 ; char a [] = "Hello World" ; static int b = 2023 ; // 初期化された静的グローバル変数void foo ( void ) { static int c = 2023 ; // 初期化された静的ローカル変数}BSSセグメントには、初期化されていない静的データ(変数と定数の両方)が含まれます。つまり、グローバル変数と、ゼロで初期化されているか、ソースコード内で明示的な初期化が行われていないローカル静的変数です。C言語の例としては、次のものがあります。
static int i ; static char a [ 12 ];ヒープセグメントには動的に割り当てられたメモリが含まれており、通常はBSSセグメントの末尾から始まり、そこからより大きなアドレスへと拡張されます。これはmalloc、calloc、realloc、freeによって管理され、brkおよびsbrkシステムコールを使用してサイズを調整できます(ただし、malloc/calloc/realloc/freeの契約を満たすためにbrk/sbrkと単一のヒープセグメントの使用は必須ではありません。mmap/munmapを使用して、プロセスの仮想アドレス空間に、連続していない可能性のある仮想メモリ領域を予約/予約解除することもできます)。ヒープセグメントは、プロセス内のすべてのスレッド、共有ライブラリ、および動的にロードされたモジュールで共有されます。
スタックセグメントには、通常メモリの上位領域に配置されるLIFO構造であるコールスタックが含まれます。「スタックポインタ」レジスタはスタックの最上位を追跡し、値がスタックに「プッシュ」されるたびに調整されます。1つの関数呼び出しでプッシュされる値の集合は「スタックフレーム」と呼ばれます。スタックフレームは、少なくとも戻りアドレスで構成されます。自動変数もスタック上に割り当てられます。
従来、スタックセグメントはヒープセグメントに隣接しており、互いに近づいて成長していました。スタックポインタがヒープポインタに到達すると、空きメモリが枯渇したことになります。アドレス空間が広くなり、仮想メモリ技術が用いられるようになった現在では、スタックはより自由に配置される傾向がありますが、それでも通常は収束方向に成長します。標準的なPC x86アーキテクチャでは、スタックはアドレス0に向かって成長します。つまり、呼び出しチェーンのより深い位置にある、より新しい項目は、数値的に低いアドレスに配置され、ヒープに近くなります。他のアーキテクチャでは、逆方向に成長します。
一部のインタプリタ型言語は、データセグメントと同様の機能を提供しており、特にPerl [ 1 ]とRuby [ 2 ]が挙げられます。これらの言語では、行__DATA__(Perl) または__END__(Ruby、旧 Perl) を含めることで、コードセグメントの終了とデータセグメントの開始が示されます。この行より前のコンテンツのみが実行され、この行より後のソースファイルの内容はファイルオブジェクトとして利用できます。PerlPACKAGE::DATAでは (例: main::DATA)、Ruby では となります。これは、ヒアドキュメント(ファイルリテラル)DATAの一種と考えることができます。