不能没有错误地跳转

时间:2012-08-07 12:29:46

标签: assembly operating-system x86 boot protected-mode

我有问题。最后几天我正在玩GDT,A20和保护模式。我有这个简单的GDT代码:

gdt_start:
gdt_null:
    dd 00000000h
    dd 00000000h

gdt_code:
    dw 0xFFFF
    dw 0
    db 0
    db 10011010b
    db 11001111b
    db 00000000b

gdt_data:
    dw 0xFFFF       
    dw 0                
    db 0                
    db 10010010b            
    db 11001111b            
    db 0

gdt_end:
gdt_ptr:
    dw gdt_end - gdt_data - 1
    dd gdt_start

install_gdt:
    cli;
    pusha
    lgdt [gdt_ptr]
    sti
    popa

    ret

你可以看到它非常简单。这是我的A20启用:

ena20:
    mov al, 0xDD
    out 0x64, al
    ret

第二阶段代码的一部分:

    call install_gdt
    call ena20

    cli
    mov eax, cr0
    or eax, 1
    mov cr0, eax

    jmp 0x8:stage3
;-------------------------------------------
;STAGE3
;-------------------------------------------
BITS 32
stage3:
    ;mov ax, 0x10
    ;mov ds, ax
    ;mov ss, ax
    ;mov es, ax
    ;mov esp, 90000h

    ;mov edi, 0xB8000
    ;mov byte [edi], 'A'

    jmp $

我试着一步一步走。我可以成功将GDT加载到它的寄存器中,启用A20并进入保护模式。但是当我尝试jmp 0x8:stage3时,我从VirtualBox收到错误:

A critical error has occurred while running the virtual machine and
the machine execution has been stopped.

(虚拟机状态现在是'Guru Meditation') 有人知道哪里有问题吗?我该怎么做才能让它发挥作用?请帮忙。

1 个答案:

答案 0 :(得分:1)

下面:

gdt_ptr:
    dw gdt_end - gdt_data - 1
    dd gdt_start

为什么GDT大小从gdt_datagdt_end,但起点是gdt_start

此外,包含GDT的实模式段如何?你如何将它“包含”在gdt_start的价值中?

下面:

    mov eax, cr0
    or eax, 1
    mov cr0, eax

    jmp 0x8:stage3

BITS 32
stage3:

根据相关的GDT条目,您希望在基数为0的段中stage3。是这样的吗? IOW,stage3的值是否等于此标签上代码的物理地址?