Assembly 在引导加载程序加载GDT之后,x86处理器如何获取指令?

Assembly 在引导加载程序加载GDT之后,x86处理器如何获取指令?,assembly,x86,operating-system,osdev,gdt,Assembly,X86,Operating System,Osdev,Gdt,在为x86编写的典型简单引导加载程序中,我们有以下代码来加载GDT并执行远跳转(请注意,在执行以下代码之前,CS是0x0): 然而,就在lgdtCS之后,它是空的,指向GDT中的空描述符。因此: 1.lgdt加载GDT之后,CPU究竟如何获取正确的指令 2.要跳远到的代码段的DPL通常为0,执行跳远时CPU是否执行权限检查?直到跳远从GDT条目加载内部CS base/limit/stuff,您才使用任何GDT条目。它甚至不是真正的保护模式 与启用分页不同(下一条指令的指令提取在写入CR0后将CS

在为x86编写的典型简单引导加载程序中,我们有以下代码来加载GDT并执行远跳转(请注意,在执行以下代码之前,CS是0x0):

然而,就在
lgdt
CS之后,它是空的,指向GDT中的空描述符。因此:

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


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

直到跳远从GDT条目加载内部CS base/limit/stuff,您才使用任何GDT条目。它甚至不是真正的保护模式

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

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

我不知道它是否算作CPL=0,或者它是否是一个特例,或者如果你的第一次跳远是到呼叫门会发生什么。如果你想要的不止这些,请看一看和/或英特尔或AMD的手册,或者其他人会回答这个问题

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: