1

在为 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:

然而,就在lgdtCS 为空之后,指向 GDT 中的空描述符。所以 :

1.在GDT被加载后,CPU究竟如何才能获取正确的指令lgdt

2.远跳转到的代码段的DPL通常为0,做远跳转时CPU是否进行权限检查?

4

1 回答 1

1

在远跳转从 GDT 条目加载内部 CS 基础/限制/东西之前,您根本没有使用任何 GDT 条目。它甚至不是保护模式。

与启用分页不同(其中下一条指令的取指在写入 CR0 后的下一条指令中将 CS:EIP 视为虚拟),直到写入段寄存器导致 CPU 实际从 GDT 读取之后才会发生段填充。

LGDT 不会更改 CS 基地址,并且您仍处于操作数大小 = 地址大小 = 16 的最大特权级别,因此ljmp指令的代码获取就会发生。(假设此代码段的执行以实模式或虚模式开始。)处于保护模式会影响将 CS 更新为 的含义8,但不会影响获取和运行执行该操作的指令。

我不知道它是否算作 CPL=0 或者它是否是一种特殊情况的正式细节,或者如果你的第一次远跳是到一个呼叫门会发生什么。如果您想要更多,请查看https://wiki.osdev.org/GDT_Tutorial和/或英特尔或 AMD 的手册,或者其他人可能会回答这个问题。

于 2020-03-22T04:46:01.363 回答