Apo*_*ain 1 memory x86 assembly osdev gdt
我知道GDT(全局描述符表)是如何实现的以及段寄存器和段描述符的使用。然而,如何/何时访问 GDT 条目呢?
是否可以通过基本 mov 指令访问,例如
mov [eax],ebx
Run Code Online (Sandbox Code Playgroud)
这是否隐式调用 ds 段寄存器,然后访问 GDT 段描述符,或者是否有其他方式访问 GDT 条目?
TL;DR:在保护模式或长模式下,只有当段寄存器加载了新的选择器(无论是相同的值还是不同的值)时,才会访问全局描述符表(GDT)或局部描述符表(LDT) 。正在加载的选择器值的位 2 确定是使用 GDT(位 2 清零)还是 LDT(位 2 置位)来确定从何处读取描述符。
当段寄存器(CS/DS/ES/SS/FS/GS)在16/时加载(无论是新值还是相同值)时,将查询GDT(或LDT)以获取描述符条目中的信息32 位保护模式或长模式。可以将值加载到段寄存器中的指令有 POP、MOV、JMP(远)、CALL(远)、RET(远)。IRET。
在实模式下,当段寄存器加载新值时,不会直接查询GDT/LDT 。
使用选择器加载段寄存器将导致适当的特权级别和访问权限检查,以确定它在正在使用的上下文中是否有效。描述符的基本权限、限制权限和访问权限将被加载到与每个段寄存器关联的段描述符高速缓存中。
段描述符缓存是 CPU 的隐藏部分,它的存在是为了加速内存访问,这样就不必为访问内存的每条指令从内存中重新加载描述符信息。当你做类似的事情时:
mov [eax], ebx
Run Code Online (Sandbox Code Playgroud)
CPU 会将EBX中的 32 位值写入内存地址DS:[eax](其中EAX包含要读取的偏移量)。除非被覆盖,否则每个内存访问都有一个隐式段关联。具有内存地址的 MOV 指令的默认值是 DS(如果内存地址使用 EBP 作为基址,则默认为 SS)。由于段寄存器中选择器所需的信息已缓存在 CPU 中,因此当指令具有内存操作数时,不会直接查询 GDT(或 LDT)。