全局描述符表 GDT 和本地段描述符表 LDT
计算机中实际存在两个表GDT、LDT,前者是全局描述符表,后者是本地段描述符表。他们都用来存放某个运行在内存中的程序的分段信息的。只不过全局描述符表是全局可见的,即每一个运行在内存中的程序都能访问这个表。操作系统的内核程序的段信息就存在GDT表里面。而LDT表是每一个在内存中的程序都包含的,这里面指明了每一个程序的段信息。
全局描述符表 (GDT) 是内存中定义处理器内存段的表。GDT 设置段寄存器的行为并帮助确保保护模式顺利运行。
GDTR
GDT 由 x86 芯片中的一个特殊寄存器GDT Register或简称为 GDTR 指向。GDTR 为 48 位长。低 16 位表示 GDT 的大小,高 32 位表示 GDT 在内存中的位置。这是 GDTR 的布局:
|LIMIT|----BASE----|
LIMIT 是 GDT 的大小,BASE 是起始地址。LIMIT 比表的长度小 1,因此如果 LIMIT 的值为 15,则 GDT 的长度为 16 个字节。
要加载 GDTR,使用指令LGDT:
lgdt [gdtr]
其中gdtr是指向包含所需 GDTR 值的 6 字节内存的指针。请注意,要完成加载新 GDT 的过程,需要重新加载段寄存器。CS寄存器必须使用远跳转加载 :
flush_gdt:
lgdt [ gdtr ]
jmp 0x08 :complete_flush
complete_flush:
mov ax , 0x10
mov ds , ax
mov es , ax
mov fs , ax
mov gs , ax
mov ss , ax
ret
GDT 表包含许多称为Segment Descriptors的条目。每个长度为 8 个字节,包含有关段的起点、段的长度和段的访问权限的信息。
struc gdt_entry_struct
limit_low: resb 2
base_low: resb 2
base_middle: resb 1
access: resb 1
granularity: resb 1
base_high: resb 1
endstruc