2016-07-16 92 views
1

我的引導程序的這個階段在0x7e0:0x0000加載。經過一些「調試」後,我發現下面的代碼在我的遠跳後會產生三重故障。如果在跳轉之前移動掛起(是的,包括實際的程序本身),則不會發生三重錯誤。對不起,我不能包含更少的代碼。我只是想確保我提供了足夠的代碼,以便不會錯過錯誤。啓用PMode後,遠程跳閘會導致三重故障?

這裏是我的代碼:

bits 16 

jmp SetUpPMode 

GTDData: 
    dd 0 
    dd 0 
    ;Code Descriptor 
    dw 0xFFFF 
    dw 0 
    db 0 
    db 10011010b 
    db 11001111b 
    db 0 
    ;Data Descriptor 
    dw 0xFFFF 
    dw 0 
    db 0 
    db 10010010b 
    db 11001111b 
    db 0 
GTDEnd: 

GDTPointer: 
    dw (GTDEnd - GTDData) - 1 
    dd GTDData 

LoadGDT: 
    lgdt [GDTPointer] 
    ret 

SetUpPMode: 
    cli 
    mov ax, 0x7E0 
    mov ds, ax 

    call LoadGDT 

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

    jmp 0x8:main 

bits 32 

main: 
    mov ax, 0x10 
    mov ds, ax 
    mov es, ax 
    mov ss, ax 
    mov esp, 0x90000 

    jmp hang 

hang: 
    ;cli 
    hlt 
    jmp hang 

我敢打賭,這個bug /錯誤是公然明顯的,但我似乎無法找到它。有人可以指出嗎? (如果它的事項,我使用虛擬盒)

+2

你應該在你的程序開始使用CLI一次,從來沒有使用STI,直到你設置一個適當的保護模式IDT。在LGDT周圍放置PUSHA/POPA也沒有意義,因爲它不會更改這些指令保存和恢復的任何寄存器。 –

+1

@RossRidge我清理了所有'sti'和'cli's,但它仍然是三重錯誤。我並不認爲你的意見是作爲答案,但我想我可能會通知你。 – DrCereal

+1

一個問題是代碼中'main'的偏移量與主保護模式代碼段的偏移量不匹配。在你的代碼中它的偏移量就像0x00xx,但是相對於保護模式代碼段它的偏移量將是0x00007exx。你或者需要調整你的代碼段的基礎或者你的程序的ORG(例如,所以它的加載時間是0000:7e00而不是07e0:0000) –

回答

4

您加載代碼,並在0x07E0:0x0000數據。因此,彙編器和鏈接化妝的基礎在0x07E0:0x0000的所有引用 - 如main,這可能是0x0020什麼的。

但是你的GDT有基礎,以0x00000000代碼段 - 所以jmp 0x8:mainJMP絕對地址0x00000020什麼 - 隔靴搔癢,其中代碼爲0x00007E20或其它地方。可以更改GDT中段的基數,也可以將代碼更改爲0x0000的實模式段。

+0

我用'org'和這些段稍微擺弄一下,它停止了三重錯誤。問題已得到解決。 – DrCereal