我正在编写自己的内核并使用此代码覆盖引导加载程序设置的全局描述符表。这是在 32 位保护模式下完成的。
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
该代码工作正常,但是我无法理解为什么 lgdt 之后的下一条指令正确执行。
据我了解,段寄存器(尤其是 CS)的值保持不变。因此 CPU 将使用旧寄存器和新表来解析指令地址jmp 0x08:complete_flush
。很有可能我的表中由旧 CS 的值指向的条目不是有效的代码段,这会导致崩溃。然而,没有这样的事情发生。为什么?
编辑:问这个是因为我的理解是 CPU 使用 CS:EIP 寄存器对解析线性地址。现在在lgdt
CS 之后会突然指向不同的条目,所以为什么执行的下一条指令是 jmp 指令