x86 从实模式切换到保护模式 CPL (Current Privilege Level)

x86 Switching to protected mode from real mode CPL (Current Privilege Level)

在 x86 中,在我们设置 PE 位 CR0 之后,我们进行远跳转以确保 CS/EIP 被更改。当我查看 x86 程序员手册中的逻辑流程时,对应于这条远 JMP 指令(保护模式),我看到如下内容:

Set RPL field of CS register to CPL;

我想确保特权级别为0。假设描述符中的DPL也为0,远JMP中选择器中的RPL也为0。描述符中的C位为0,因此它是不合格代码-段案例。手册说 CPL 是 CS 中的最后两位。这意味着,在 far JMP 之前,CS 应该包含一个最后两位为 00 的值。所以,当我最初处于实模式时,我是否应该确保 CS 在我之前有一些符合这个条件的值执行远 JMP? 如果换个说法,当我们从实模式切换到保护模式时,CPL 是什么?

[...] what is the CPL when we switch from real mode to protected mode?

当实模式处于活动状态时,CPL 被设置为适合实模式的某个值 "the needs"(我猜它是零)。当跳转到保护模式时,它被分配段选择器的最低有效两位的值。

[...] should I make sure that CS has some value that conforms to this condition before I execute the far JMP?

不,这无关紧要。从技术上讲,CPU 对段寄存器中的值不感兴趣,而是对它们的影子寄存器感兴趣,"segment descriptor caches." 这些影子寄存器包含 RPL、DPL、CPL、基地址以及其他内容段描述符。实模式不需要的值(如 RPL)设置为适合实模式的值。当从实模式切换到保护模式时,实模式中不需要的值变为必需值,并使用从 GDT 获得的值进行初始化。当切换回实模式时,与保护模式相关的值再次变得无关紧要,从而获得指定的特定值1.

毕竟,CPU 直接从段描述符缓存中读取,而不是从段寄存器中读取。

有关此主题的更多信息,请阅读 this 和其中链接的论文。


1 实际上,这并不完全正确。了解 Unreal Mode