我有一个代码:
[org 0x7c00]
CODE_SEG equ GDT_code - GDT_start
DATA_SEG equ GDT_data - GDT_start
cli
lgdt [GDT_descriptor]
mov eax, cr0
or eax, 1
mov cr0, eax
jmp CODE_SEG:start_protected_mode
jmp $
GDT_start:
GDT_null:
dd 0x0
dd 0x0
GDT_code:
dw 0xffff
dw 0x0
db 0x0
db 0b10011010
db 0b11001111
db 0x0
GDT_data:
dw 0xffff
dw 0x0
db 0x0
db 0b10010010
db 0b11001111
db 0x0
GDT_end:
GDT_descriptor:
dw GDT_end - GDT_start - 1
dd GDT_start
[bits 32]
start_protected_mode:
mov ax, DATA_SEG
mov ds, ax
mov es, ax
mov al, "A"
mov ah, 0x0f
mov [0xb8000], ax
jmp $
times 510-($-$$) db 0
dw 0xaa55
它在 qemu 上运行良好,但是当我尝试在真实电脑上启动它时,它只是重新启动。我在互联网上发现,我的问题是段寄存器。我该如何设置它们,以便程序可以在真实的 PC 上开始运行?
我尝试将 DS 和 ES 设置为 0x07C0,但随后程序也停止在 qemu 上工作。
首先,您必须将
ds
寄存器设置为 zero
,因为您工作的内存区域低于 64KB。这是由 qemu
完成的,很可能是通过其他虚拟机为您完成的。但现在迁移到物理机的过程中,你必须自己处理:
xor ax, ax
mov ds, ax
mov es, ax ; you may want this as well
然后,不要忘记将
stack
设置为这样的内容或您想要的其他区域:
mov ax, 0x9000
mov ss, ax
mov sp, 0xFC00 ; ss:sp (linear) -> 9FC00h (which is below BIOS area)