进入保护模式后理解远跳问题

ali*_*eza 1 x86 assembly protected-mode bootloader

在我的引导加载程序代码中有一个部分,我们通过加载 GDT 并启用控制寄存器位来将 cpu 切换到保护模式。

这是引导加载程序代码的部分:

init_pm:
    ...
    cli
    lgdt [GDT_descriptor]

    mov eax, cr0
    or eax, 1
    mov cr0, eax

    ; far jump
    jmp CODE_SEG:start_protected_mode

[bits 32]
start_protected_mode:
    ...
Run Code Online (Sandbox Code Playgroud)

这些是常数:

CODE_SEG equ code_descriptor - GDT_start
DATA_SEG equ data_descriptor - GDT_start
Run Code Online (Sandbox Code Playgroud)

所以我的问题如下:

  1. 什么是远跳?

  2. 进入保护模式到底对CPU有什么影响?

  3. 什么是CODE_SEG以及为什么我们将它与偏移量 start_protected_mode一起使用?我们不能像这样进行正常的跳跃吗jmp start_protected_mode?我知道它是 GDT 中代码描述符的位置,但这是否会自动被 cpu 识别为引导加载程序代码的位置?

prl*_*prl 6

  1. 远跳转是一种加载 CS 寄存器以及 E/RIP 的跳转。

  2. 设置 CR0 的位 0 会改变 CPU 执行段寄存器加载的方式。它还改变了许多其他指令的操作方式。但是,它不会改变缓存的CS描述符信息。所以进入保护模式后,CPU仍然以16位模式执行指令。

  3. GDT中的代码段描述符是一个32位的代码段。将此描述符加载到 CS 中会导致处理器开始以 32 位模式执行指令。如果您使用近跳转而不是远跳转,处理器会尝试将指令解释为 16 位指令。