切换到保护模式后"呼叫"

mar*_*tus 5 assembly kernel att

我正在尝试切换到intel x86中的保护模式.

我已经用lgdt加载了我的gdt,将cr0的P标志设置为1和所有段选择器但是当我从函数调用返回时,我无法调用任何其他函数或者我得到此错误

qemu: fatal: Trying to execute code outside RAM or ROM at 0xfeeb7c5b
Run Code Online (Sandbox Code Playgroud)

这是我的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
Run Code Online (Sandbox Code Playgroud)

我的电话

_start:
    call switch_to_pmode
    call foo // <----- Ouch!
Run Code Online (Sandbox Code Playgroud)

谢谢

Gun*_*iez 3

您需要确保汇编器使用.code32(或use32在 nasm 中)指令将保护模式开关后面的代码转换为 32 位代码。

此外,在保护模式例程之后您的返回地址不再有效。之后你就无法再回到任何事情了。相反,将 esp 设置为有用的值并继续。