セグメントの仕組み

GDTについては少し調べたけれど、実際の所セグメントの仕組みがどのように動くのか正確に理解してなかったので、もう一度確認してまとめてみた。
■セグメント方式
x86 CPUではメモリ管理方式としてセグメント方式を使用している。
セグメント方式では、メモリ空間をセグメントと呼ばれる可変長の区画に分けて管理する。
ディスクリプタテーブル
セグメントの定義はOSによって行われ、ディスクリプタテーブルと呼ばれるテーブルに保存される。
ディスクリプタ上の個々のセグメント定義レコードはセグメントディスクリプタと呼ばれ、セグメントベース(セグメントの開始アドレス)、リミット(セグメントの大きさ)と属性などを持つ。
プログラムからセグメントを指定する時には、ディスクリプタテーブルのインデックス値を使う。
この値をセグメントアドレス又はセレクタと呼ぶ。
■セグメントレジスタ
x86 CPUでは6つのセグメントレジスタを持っている。
・CS 現在のコードセグメントを指定する
・DS 現在のデータセグメントを指定する
・SS 現在のスタックセグメントを指定する
・ES,FS,GS 追加のデータセグメントレジスタ 他のデータセグメントレジスタへもアクセスさせる時に使う
現在使用しているセグメントとして、CS/DS/SSに有効なセレクタ値が指定されている必要がある。
■メモリアドレスの求め方
ちょっと想像が入ってるので怪しいけど多分こう:
1.オペコードでオフセットアドレスが指定される
(色々アドレスの指定方法があるが、結局はオフセットアドレスになってるはず
 セグメントを明示する時は例外だけど)
2.セグメントレジスタから現在のセグメントを調べる
(コードへのアクセスならCS、データへのアクセスならDS)
3.セグメントディスクリプタからセグメントベースを調べる
4.セグメントベース+オフセットアドレスでメモリアドレスを求める
■現在のOSでの使われ方
現在のOSでは、セグメントベースアドレス:0x0  リミット: 4GBと定義されたセグメントがコード・データ・スタックセグメント向けに定義されており、これを固定的に使っているだけになっている。
つまり、事実上フラットメモリモデルとして使われている。
後付けで足されたページング機構を使う事でフラットメモリモデルで仮想メモリシステム・メモリ保護などが実現出来、セグメントを活用するよりも使いやすい事からこのような使い方をするのが一般的になっている。