我混淆了一些关于在 boot/setup.s 文件中启用 PE 的汇编代码 Linux 0.11

I am confusing some assembly code about enable PE within boot/setup.s file in Linux 0.11


相关的汇编代码位于boot/setup.s,我把它们贴在下面:

    mov ax,#0x0001        ! protected mode (PE) bit 
    lmsw ax               ! This is bit!
    jmpi 0,8              ! jmp offset 0 of segment 8 (cs)

前两行在CR0控制寄存器中做了相应的位变化
所以,我的问题是:
当执行指令 lmsw ax 时, ip 寄存器指向下一条指令 jmpi 0,8 .
更确切地说,在这一点上,cs:ip 指向指令的内存位置 jmpi 0,8 .
但是执行指令lmsw ax后,PE机制被启用。 cs 值现在
表示段选择器,但相应的 GDT 描述条目不是
为它做好准备。 GDT 仅包含位于 1 和 2 respectively.So、I
中的两个有效条目 认为 cs:ip 指定的下一条指令不是指令 jmpi 0,8.
cs:ip 现在指向一个无效的内存地址。上面最后一条指令 jmpi 0,8 是用到的 无法将正确的值放入 cs 和 eip 寄存器。我知道我错了,因为 Linux 0.11是经过长期实践验证的。请帮我指出我很make.Thanks的错误。

CPU 不会在每次使用段寄存器时都在 GDT(或 LDT)中查找选择器。它只在加载段寄存器时读取内存中的描述符table。然后它将信息存储在段描述符中 cache.The 同样的事情发生在实模式中,当段寄存器加载一个值时,该值用于在描述符缓存中创建一个条目。然后,无论何时使用该段,无论是在实模式还是保护模式下,处理器都会使用存储在高速缓存中的值。

当您从实模式切换到保护模式时,段寄存器的 none 发生变化,描述符缓存中的条目的 none 发生变化。 CS 寄存器的缓存条目与之前相同,因此 CPU 按预期执行以下指令。直到执行了下面的远跳转指令,CS寄存器的值才发生变化,然后用新的保护模式条目替换旧的实模式描述符条目。