2016-07-16 1 views
1

ブートローダーのこの段階は0x7e0:0x0000にロードされています。いくつかの "デバッグ"の後、次のコードが私のの遠いジャンプの後に三重のフォールトを生成することを発見しました。私がジャンプの前に(実際の手続きそのものを含む)ハングを移動すると、それは3倍の誤りではありません。申し訳ありませんが少ないコードを含めることはできませんでした。私は、バグを逃さないように十分なコードを提供していることを確認しようとしています。ここで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 

賭けます。誰かがそれを指摘してくれますか? (問題があれば、私はバーチャルボックスを使用しています)

+2

プログラムの開始時にCLIを1回使用し、適切な保護モードIDTを設定するまではSTIを使用しないでください。 LGDTの周りにPUSHA/POPAを置くことは、それらの命令によって保存され、復元されたレジスタを変更しないので意味がない。 –

+1

@RossRidge私はすべてのstiとcliをクリアしましたが、それでもまだ3重の障害があります。私は本当にあなたのコメントが答えとして意図されているとは思わないが、私はあなたにも通知するかもしれないと思った。 – DrCereal

+1

1つの問題は、コード内の 'main'のオフセットが、保護されたモードのコードセグメントのメインのオフセットと一致しないことです。あなたのコードでは、そのオフセットは0x00xxのようなものですが、保護されたモードのコードセグメントに対するオフセットは0x00007exxになります。あなたは、あなたのコードセグメントベースまたはあなたのプログラムのORGを調整する必要があります(例えば、07:00:0000の代わりに0000:7e00でロードする) –

答えて

4

コードとデータを0x07E0:0x0000にロードします。したがって、アセンブラとリンカの参照はすべて、mainなどの0x07E0:0x0000に基づいています。0x0020などです。

しかし、あなたのGDTは0x00000000に基づいて、コードセグメントを持っている - ので、絶対アドレス0x00000020か何かにjmp 0x8:mainだろうJMP - どこコードが0x00007E20またはどこにある場所の近く。 GDT内のセグメントのベースを変更するか、0x0000の実モードセグメントから機能するようにコードを変更します。

+0

私は 'org'とセグメントをちょっと試してみました.3重のフォルトを止めました。問題は修正されました。 – DrCereal

関連する問題