我正在尝试在英特尔x86中切换到保护模式。
我已经使用lgdt加载了我的GDT,将cr0的P标志设置为1,并设置了所有段选择器,但当我从函数调用返回时,我无法调用任何其他函数,否则就会出现此错误。
qemu: fatal: Trying to execute code outside RAM or ROM at 0xfeeb7c5b
这是我的switch_to_pmode函数:
gdtr:
.short 23 // limit
gdtr_base:
.long 0 // base
switch_to_pmode:
movl $null_segment, %eax // Address of the first byte of the GDT
movl %eax, gdtr_base
cli // disable interrupts
lgdt (gdtr)
movl %cr0, %eax
or $0x1, %eax
movl %eax, %cr0 // Set the PE flag
push $0x8
push $reload_segments
lret
reload_segments:
movl $0x10, %eax
movl %eax, %ds
movl %eax, %ss
movl %eax, %es
movl %eax, %fs
movl %eax, %gs
ret
foo:
ret
我的通话记录
_start:
call switch_to_pmode
call foo // <----- Ouch!
谢谢你。
push $8; push reload_segments; retl
解读为一种创造性的执行远跳转的方式。但是你描述的方法是规范的方式,而且以那种方式可靠地工作。 - Gunther Piez