跳转到保护模式正在重新启动 QEMU

Jump to Protected Mode is restarting QEMU

我已经成功编写了实模式代码。但麻烦始于 32 位保护模式。在跳转到保护模式之前,我使用 cli 禁用了中断, 使用 lgdt 加载 GDT 和 在 cr0 中设置 32 位模式位。但是 QEMU 正在无限重启。以下是代码

boot.asm:

[BITS 16]
            BOOTSEG equ 0x7c00
            DATASEG equ 0x07c0
            STACKSEG equ 0x17c0
            EXTRASEG equ 0x37c0
            STACKPOINT equ 0x0000

            BLACKONWHITE equ 0x0F
            YELLOWONBLUE equ 0x1E

            VIDEO_MEMORY equ 0xb8000

            global _start

_start:

            xor ax, ax

            mov ax, STACKSEG
            mov ss, ax              ;initializing stack segment
            mov sp, STACKPOINT
            
            mov ax, DATASEG
            mov ds, ax              ;initializing data segment

            mov ax, EXTRASEG
            mov es, ax               ;initializing extra segment

            call Switch_To_Pm

            %include "./screen.asm"
            %include "./lib.asm"
            %include "./gdt.asm"
            %include "./protected_mode/switch_to.asm"

[bits  32]

Begin_Pm:
            jmp $

            times 510 - ($ - $$) db 0

            dw 0xAA55

gdt.asm:

gdt_start:

null_descriptor:
                dd 0x0
                dd 0x0

code_descriptor:
                dw 0xffff
                dw 0x0
                db 0x0
                db 10011010b
                db 11001111b
                db 0x0

data_descriptor:
                dw 0xffff
                dw 0x0
                db 0x0
                db 10010010b
                db 11001111b
                db 0x0

gdt_end:

gdt_descriptor:
                dw gdt_end - gdt_start - 1
                dd gdt_start

CODE_SEG equ code_descriptor - gdt_start

DATA_SEG equ data_descriptor - gdt_start

protected_mode/switch_to.asm:

    [BITS 16]
Switch_To_Pm:
                cli
                lgdt [gdt_descriptor]
                mov eax , cr0
                or eax , 0x1
                mov cr0 ,eax
                jmp CODE_SEG:Init_Pm

[BITS 32]

Init_Pm:
                mov ax, DATA_SEG
                mov ds, ax
                mov ss, ax
                mov es, ax
                mov fs, ax
                mov gs, ax

                call Begin_Pm

lib.asm 包含使用 int 0x15 的延迟例程和 screen.asm 包含 BIOS 例程以打印文本实模式。

以下是我用来构建的命令

nasm -fbin -o boot.bin boot.asm
qemu boot.bin

不知道为什么 QEMU 会无限重启。直到实模式的代码运行良好。可能切换到保护模式有问题。

事先感谢任何帮助

我想我已经找到问题所在了。问题出在线路上 jmp CODE_SEG:Init_Pmprotected_mode/switch_to.asm 中。我应该为远跳添加 0x7c00 的偏移量。
相反,我使用 [org 0x7c00] 并重写了实模式和保护模式代码,它起作用了。