我知道如何实现 GDT(全局描述符表)以及如何使用段寄存器和段描述符。但是如何/何时访问 GDT 条目?
是否在基本 mov 指令中访问,例如
mov [eax],ebx
这是否隐式调用 ds 段寄存器,然后访问 GDT 段描述符,还是有其他方式可以访问 GDT 条目?
TL;DR : 全局描述符表 (GDT) 或局部描述符表 (LDT) 仅在处于保护模式或长模式时使用新选择器(无论是相同值还是不同值)加载段寄存器时访问. 正在加载的选择器值的第 2 位确定是使用 GDT(第 2 位清零)还是 LDT(第 2 位设置)来确定从何处读取描述符。
当在16 / 32 位保护模式或长模式。可以将值加载到段寄存器中的指令是 POP、MOV、JMP(远)、CALL(远)、RET(远)。伊雷特。
在实模式下,当段寄存器加载新值时,不会直接查询 GDT/LDT。
使用选择器加载段寄存器将导致适当的特权级别和访问权限检查以确定它在使用它的上下文中是否有效。描述符的基本、限制和访问权限将被加载到与每个段寄存器关联的段描述符缓存中。
段描述符缓存是 CPU 的隐藏部分,它的存在是为了加快内存访问速度,这样就不必为访问内存的每条指令从内存中重新加载描述符信息。当您执行以下操作时:
mov [eax], ebx
CPU 会将EBX中的 32 位值写入内存地址DS:[eax]
(其中EAX包含要读取的偏移量)。除非被覆盖,否则每个内存访问都有一个隐含的段。带有内存地址的 MOV 指令的默认值为 DS (如果内存地址使用 EBP 作为基址,则为 SS)。因为段寄存器中的选择器所需的信息被缓存在 CPU 中,所以当指令具有内存操作数时,不会直接查询 GDT(或 LDT)。