【发布时间】:2021-07-12 07:56:33
【问题描述】:
我已经成功编写了实模式代码。但问题始于 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 正在无限重启。直到实模式的代码运行良好。切换到保护模式可能有问题。
感谢任何帮助
【问题讨论】:
-
重启可能是三重故障。 Qemu 有办法记录所有故障吗?
-
您可能希望在通话前加载 esp。我不确定 esp 的高位是否保证为零。
-
你确定 Qemu 在 7c00 加载你的代码吗?
-
@prl 我做了 qemu boot.bin -D ./log.txt。但是 qemu 没有在文件中记录任何内容
-
尝试使用以下选项运行 qemu:
-d int -no-reboot -no-shutdown(和-D,如果您想登录到文件)。这应该告诉您发生了哪些异常,并且它将在第一次三重故障后停止,而不是无休止地重新启动。
标签: assembly x86 nasm protected-mode