从 16 位实模式 (x86) 切换到 32 位保护模式
Switching to 32 bit protected mode from 16 bit real mode (x86)
这是将 cpu 切换为 32 位模式的标准代码片段..
cli
lgdt [gdt_descriptor] ; Assume a well-defined GDT
mov eax, cr0
or eax, 0x1
mov cr0, eax; Is this the exact moment when the processor switches to 32 bit mode?
jmp CODE_SEG:pipeline_flush ; Here CODE_SEG is 0x08,i.e, the segment descriptor after the NULL descriptor in the GDT
[bits 32]
pipeline_flush:
这里的远跳转指令是一个 16 位(?)编码指令....但处理器处于 32 位模式....
如果我将代码更改为:
[bits 32]
jmp CODE_SEG:pipeline_flush
代码失效...
这是为什么?
设置CR0的第0位后,处理器处于16位保护模式,所以指令作为16位指令执行。
BITS 32 指令使 jmp 指令在偏移量部分使用 32 位进行汇编。处理器将偏移量的高 16 位视为段。由于它不是有效的代码段,因此引发#GP。
这是将 cpu 切换为 32 位模式的标准代码片段..
cli
lgdt [gdt_descriptor] ; Assume a well-defined GDT
mov eax, cr0
or eax, 0x1
mov cr0, eax; Is this the exact moment when the processor switches to 32 bit mode?
jmp CODE_SEG:pipeline_flush ; Here CODE_SEG is 0x08,i.e, the segment descriptor after the NULL descriptor in the GDT
[bits 32]
pipeline_flush:
这里的远跳转指令是一个 16 位(?)编码指令....但处理器处于 32 位模式.... 如果我将代码更改为:
[bits 32]
jmp CODE_SEG:pipeline_flush
代码失效...
这是为什么?
设置CR0的第0位后,处理器处于16位保护模式,所以指令作为16位指令执行。
BITS 32 指令使 jmp 指令在偏移量部分使用 32 位进行汇编。处理器将偏移量的高 16 位视为段。由于它不是有效的代码段,因此引发#GP。