【问题标题】:Why does switching to protected restarts the machine?为什么切换到受保护会重新启动机器?
【发布时间】:2013-10-11 16:06:02
【问题描述】:

我正在尝试创建非常简单的 64 位操作系统。我试图先进入保护模式,但此时我失败了。

当我执行远跳转到 32 位时,机器重新启动。

我的代码通过地址 0x100 的另一个汇编程序加载到内存中。

代码是用 nasm 编译的,我正在使用 qemu -fda 运行程序。

这是我目前得到的代码:

[BITS 16]

jmp _start

_start:
    cli

    lgdt [GDT64]

    ; Switch to protected mode
    mov eax, cr0
    or al, 1b
    mov cr0, eax

    ; Desactivate pagination
    mov eax, cr0
    and eax, 01111111111111111111111111111111b
    mov cr0, eax

    jmp (CODE_SELECTOR-GDT64):pm_start

[BITS 32]

pm_start:
    jmp $

GDT64:
    NULL_SELECTOR:
        dw GDT_LENGTH   ; limit of GDT
        dw GDT64        ; linear address of GDT
        dd 0x0

    CODE_SELECTOR:          ; 32-bit code selector (ring 0)
        dw 0x0FFFF
        db 0x0, 0x0, 0x0
        db 10011010b
        db 11001111b
        db 0x0

    DATA_SELECTOR:          ; flat data selector (ring 0)
        dw  0x0FFFF
        db  0x0, 0x0, 0x0
        db  10010010b
        db  10001111b
        db  0x0

    LONG_SELECTOR:  ; 64-bit code selector (ring 0)
        dw  0x0FFFF
        db  0x0, 0x0, 0x0
        db  10011010b       ;
        db  10101111b
        db  0x0

   GDT_LENGTH:

如果我在跳远之前执行jmp $,它可以工作,程序会正确停止,但是当跳远完成时,它会重新启动机器。

我是不是忘了设置一个段或类似的东西?

【问题讨论】:

    标签: assembly x86 intel qemu protected-mode


    【解决方案1】:

    正如您的评论所说,您需要 GDT 的线性地址。您似乎没有指定任何 ORG 指令,因此汇编器将使用基地址 0,这与运行时的地址不匹配。

    另外,不确定如何在0x100 加载代码,引导扇区通常在0x7c00 加载。

    解决方案可以很简单,只需在文件顶部指定 ORG 0x7c00

    【讨论】:

    • 天哪,我已经试过了,但我忘了重置段寄存器,现在,它工作得很好。谢谢。
    猜你喜欢
    • 2011-10-02
    • 1970-01-01
    • 2018-04-21
    • 1970-01-01
    • 2011-12-14
    • 1970-01-01
    • 2016-06-01
    • 2019-10-09
    • 2011-08-04
    相关资源
    最近更新 更多