在为 x86 编写的典型简单引导加载程序中,我们有以下代码来加载 GDT 并执行远跳转(请注意,在执行以下代码之前 CS 为 0x0):
lgdt gdtdesc
movl %cr0, %eax
orl $1, %eax
movl %eax, %cr0
# Jump to next instruction, but in 32-bit code segment.
# Switches processor into 32-bit mode.
ljmp $0x8, $protcseg
.code32 # Assemble for 32-bit mode
protcseg:
然而,就在之后lgdt
CS为null,指向GDT中的一个空描述符。所以 :
1.GDT加载后CPU到底如何才能取到正确的指令lgdt
?
2.远跳转到的代码段的DPL通常为0,CPU在远跳转时是否进行权限检查?
在远跳转从 GDT 条目加载内部 CS 基础/限制/内容之前,您根本没有使用任何 GDT 条目。它不是really甚至是保护模式。
与启用分页(在写入 CR0 后,下一条指令的取指令将 CS:EIP 视为下一条指令中的虚拟)不同,直到写入段寄存器导致 CPU 实际从 GDT 读取之后,段填充才会发生。
CS 基地址不会被 LGDT 更改,并且您仍然处于操作数大小 = 地址大小 = 16 的最大特权级别,因此对ljmp
指令就这样发生了。 (假设此代码片段在真实或虚幻模式下开始执行。)处于保护模式会影响将 CS 更新为8
,但不影响获取和运行执行此操作的指令。
我不知道它是否算作 CPL=0 还是特殊情况,或者如果你的第一次远跳是调用门会发生什么。如果您想要更多,请看一下https://wiki.osdev.org/GDT_Tutorial和/或 Intel 或 AMD 的手册,或者也许其他人会回答这个问题。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)