プロテクトモード時のセグメント機構は、リアルモード時のそれとは大きく異なります。リアルモードの場合、メモリへのアクセス範囲は1MByte(0x00000-0xfffff)に制限されています。またセグメントレジスタには、セグメントアドレスをセットする事によりメモリのアクセスを行います。
一方、プロテクトモードの場合、メモリのアクセス範囲は4GByte(0x00000000-0xffffffff)まで拡張されていて、セグメントレジスタには、メモリのアクセス範囲やアクセス属性が設定された、ディスクリプタ・テーブル[Descriptor Table]のセレクタ値と呼ばれるインデックス値をセットする事によりメモリアクセスが行われます。
リアルモードとプロテクトモードのセグメントの違い
セレクタは、セグメントのアドレス・サイズ・属性を格納しておく、ディスクリプタ・テーブル[Descriptor Table]のインデックスとなっていて、CPUはその内容に従い物理メモリーにアクセスを行う。
また、ディスクリプタ・テーブルのアドレスを格納しておくGDTR[Global Descriptor Tbale Register]があり、CPUはこの値を使用して、ディスクリプタ・テーブルにアクセスを行う。
プロテクトモードのセグメント機構
アドレス変換を行う時、CPUは任意のメモリ上に存在するディスクリプタ・テーブルを使用するが、これを使用するためには、CPUはあらかじめディスクリプタ・テーブルのアドレスを知っておく必要がある。
GDTRは、このディスクリプタ・テーブルのアドレスを設定するために使用する。このレジスタに、ディスクリプタ・テーブルのリニアアドレスを設定することによりCPUは、ディスクリプタ・テーブルを参照できるようになる。
GDTRの構成
GDTRのbit構成
bit |
意味 |
詳細 |
0-15 | Table Limit |
ディスクリプタ・テーブルのLimit値
(テーブルのbyte数-1)がセットされる。
|
16-47 | Linear Base Address |
使用するディスクリプタ・テーブルのリニア・アドレス
|
GDTRに値をロードするためには、6バイトのメモリ上に値をセットしておき、これをLGDT命令によりCPUにロードする。
メモリ上の値は、16bitの範囲(6byteのデータ・オペランドの下位2byte)のLimit値と32bitのベース・アドレス(データ・オペランドの上位4vyte)のLinear Base Addressがレジスタにロードされる。
LGDT
セレクタは、16 ビットのセグメント識別子である。これは、セグメントを直接に指すのではなく、その代わりにセグメントを定義するセグメント・ディスクリプタを指す。
セグメント・セレクタは、次の構成となっている。
セグメント・セレクタの構成
セグメント・セレクタのbit構成
bit |
FLAG |
意味 |
詳細 |
0-1 | RPL | 要求特権レベル |
セレクタの特権レベルを指定する。特権レベルは0 〜 3の範囲が可能であり、0 が最も特権レベルが高い。
これにより、動作レベル(CPL[Current Privilege Level])が高いプログラムでも一時的に、特権レベルを落としてメモリにアクセスする事が可能である。
(CPLが低いプログラムがRPLを高くしてもこれは無効となる)
|
2 | TI | テーブルインジケータ |
使用するディスクリプタ・テーブルを指定する。このフラグをクリアするとGDTが選択され、セットするとLDTが選択される。
|
3-15 | Index | インデックス |
ディスクリプタ・テーブルのインデックス値をセットする。
|
プロテクトモードでは、セレクタ値をセグメントレジスタにセットする事により、物理アドレスにアクセスするのであるが、CPUはこの時、メモリ上に設定された、Segment Descriptor Tableを参照してアドレス変換を行う。
Segment Descriptorは、セグメントのサイズと位置、およびアクセス制御情報とステータス情報をCPUに提供する。
また、Descriptorには、システム中に1つだけ存在し、全てのプログラムから共通にアクセスするセグメントを定義するGlobal Descriptor Table[GDT]、タスク単位に存在するLocal Descriptor Table[LDT]、割込みの設定に使われるInterrupt Descriptor Table[IDT]がある。
Segment Descriptor Table