全局描述符表 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

参考链接