我在x86程序集中构建内核,使用Qemu进行模拟。我有一个从cd加载到0x7C00的引导加载程序。如果我放置代码:
[BITS 16]
[ORG 0x7E00]
jmp RealModeStart
RealModeStart:
mov si, Message
call PrintString
cli
xor ax, ax
mov ds, ax
mov es, ax
mov ax, 0x09000
mov ss, ax
mov sp, 0xFFFF
sti
call InitGDT
cli
mov eax, cr0
or eax, 1
mov cr0, eax
jmp 0x8:PModeStart
InitGDT:
cli
pusha
lgdt [GDTPointer]
sti
popa
ret
GDTStart:
;NullDescriptor:
dd 0
dd 0
;CodeDescriptor: ; Code Descriptor
dw 0x0FFFF ; Limit Low
dw 0x0000 ; Base Low
db 0x00 ; Base Middle
db 10011010b ; Access
db 11001111b ; Granularity
; 1111 Segment Limit, OS use, Zero, 32-bit Segment, Limit Mul 4K
db 0x00 ; Base High
;DataDescriptor: ; Data Descriptor
dw 0x0FFFF ; Limit Low
dw 0x0000 ; Base Low
db 0x00 ; Base Middle
db 10010010b ; Access
db 11001111b ; Granularity
db 0x00 ; Base High
GDTEnd:
GDTPointer:
dw GDTEnd - GDTStart - 1
dd GDTStart
PModeStart:
mov ax, 0x10
mov ds, ax
mov es, ax
mov ss, ax
mov esp, 0x090000
cli
hlt
在引导程序中,它工作正常。没有三重缺陷。但是,如果我使用int 0x13在0x7E00加载内核,尽管放置[ORG 0x7E00],Qemu三重故障并继续重启,这是三重故障的症状。
据我所知,内核的行为就像GDT一样无效。我知道0x7E00是正确的起始地址,因为我的代码中稍后声明的字符串被正确引用。
我做错了什么?