GDTR(Global Descriptor Table Register,全局描述符表寄存器)是 x86 处理器内部的一个专用寄存器,它的唯一职责就是告诉 CPU 全局描述符表(GDT)在哪里。
形象地理解,GDTR 相当于存储了 GDT 的“定位信息”,让 CPU 在任何时候都能根据其中的数据找到并访问 GDT。
核心功能:存储 GDT 的位置与大小
GDTR 存储了 GDT 两个最关键的信息:
| 字段 | 大小 | 描述 |
|---|---|---|
| 基地址(Base Address) | 32位(保护模式)/ 64位(长模式) | GDT 在线性地址空间中的起始地址。 |
| 界限(Limit) | 16位 | GDT 的字节大小减 1,即 GDT 的最大有效偏移。 |
如何加载和读取 GDTR
GDTR 的内容由两个专用指令控制:
| 指令 | 功能 | 特权级 |
|---|---|---|
lgdt | 将内存中的一个 6/10 字节数据加载到 GDTR,从而设置 GDT 的基地址和界限。 | 特权指令(Ring 0) |
sgdt | 将 GDTR 的当前值存储到内存中,用于读取当前的 GDT 信息。 | 可在任何特权级下使用(常用于调试) |
与段选择子(Segment Selector)的联动
当执行一条访问内存的指令时,CPU 会这样使用 GDTR:
查看段寄存器:从
CS、DS等段寄存器中读取段选择子(一个 16 位的索引)。计算偏移:根据段选择子中的索引值×8,得到在 GDT 中的偏移量。
获取描述符:将GDTR 中的基地址加上这个偏移量,从 GDT 中读取对应的 8 字节段描述符。
执行检查:CPU 检查描述符中的权限、段界限等,确认无误后,才进行后续的内存访问。
例如,当执行mov ax, [0x1234]时,如果DS寄存器指向 GDT 中的某个数据段,CPU 就会依据 GDTR 定位到该段描述符,从而知道这个数据段的基地址、大小和权限。
与 IDTR 的对比
GDTR 和另一个寄存器IDTR(中断描述符表寄存器)结构非常相似,但用途不同:
| 寄存器 | 指向的表 | 用途 |
|---|---|---|
| GDTR | GDT(全局描述符表) | 管理内存段(分段机制) |
| IDTR | IDT(中断描述符表) | 管理中断和异常处理程序 |
它们都存储一个“基地址+界限”对,lgdt/sgdt与lidt/sidt指令也一一对应。
重要注意事项
无法直接访问:GDTR 不能像通用寄存器(如
rax)那样被指令直接读写,只能通过lgdt和sgdt间接操作。特权级限制:
lgdt只能在最高特权级(Ring 0)执行,这是操作系统内核的领地。普通应用程序无权修改 GDTR。系统初始化:在 x86 处理器上电后,GDTR 有一个默认值,但操作系统在进入保护模式前,必须用
lgdt加载自己定义的 GDT。
总而言之,GDTR 是 CPU 内部的一个指针寄存器,它存储了 GDT 的内存地址和大小,是 x86 分段机制得以运行的基础设施。