現在、私は低レベルのプログラミングスキルを磨くためにx86 Assemberで遊んでいます。現在、私は32ビット保護モードのアドレス指定方式に少し問題があります。アセンブラがGDTで保護モードでジャンプする
状況は以下の通りです:
私が保護モードにCPUを切り替えて、コードに応じてラベルにジャンプ0x7e0でロードされたプログラムを持っている:
[...]
code to switch CPU in Protected Mode
[...]
jmp ProtectedMode
[...]
bits 32
ProtectedMode:
.halt:
hlt
jmp .halt
これには絶対に正常に動作します遠い"jmp ProtectedMode"は、このプログラムにオフセット0(最初はorg 0)がロードされているため、プリフェッチキューをクリアするために明示的な遠方ジャンプを行わずに動作し、コードセグメントが正しい位置を指し示すようにします。
現在の問題は、 "ProtectedMode"ラベル内で、0x8000で読み込まれた他のプログラムにジャンプしたいということです(これをメモリダンプでチェックしました。ローディング機能が正しく動作し、プログラムがロードされました0x8000に正しく)。
CPUは現在保護モードであり、もはやRealModeではないため、アドレス指定スキーマは異なります。 ProtectedModeは、ディスクリプタセレクタを使用してディスクリプタテーブルのベースアドレスと制限を検索し、指定されたオフセットを追加し、物理アドレスを取得します(これはわかっています)。したがって、ProtectedModeに入る前にGDTをインストールする必要がありました。私はこれまでであることを理解していない何
lgdt [gdtr]
は、どのように私は今、物理的にジャンプしない経由で登録
%ifndef __GDT_INC_INCLUDED__
%define __GDT_INC_INCLUDED__
;*********************************
;* Global Descriptor Table (GDT) *
;*********************************
NULL_DESC:
dd 0 ; null descriptor
dd 0
CODE_DESC:
dw 0xFFFF ; limit low
dw 0 ; base low
db 0 ; base middle
db 10011010b ; access
db 11001111b ; granularity
db 0 ; base high
DATA_DESC:
dw 0xFFFF ; data descriptor
dw 0 ; limit low
db 0 ; base low
db 10010010b ; access
db 11001111b ; granularity
db 0 ; base high
gdtr:
Limit dw 24 ; length of GDT
Base dd NULL_DESC ; base of GDT
%endif ;__GDT_INC_INCLUDED__
とGDTにロードされます。
鉱山は、次のように探していますProtectedModeのアドレス0x8000はGDTを使用していますか?
最初の考えは、0x7e00(現在のプログラムがロードされていた)を指すコード記述子(CODE_DESC)を選択し、0x8000(512バイト)に到達するのに必要なオフセットを使用して、ジャンプ命令:
jmp CODE_DESC:0x200
これは機能しません。
jmp 0x7e0:0x200
...どちらか動作しません
あなたは私がここで行方不明です何任意のアイデアを持っていますか?たぶん、私は32ビットProtectedModeアドレッシングスキームとGDTの使用法に不可欠な何かを理解していないかもしれません。
[EDIT]コンプリートコード:
bits 16
org 0 ; loaded with offset 0000 (phys addr: 0x7e00)
jmp Start
Start:
xor ax, ax
mov ax, cs
mov ds, ax ; update data segment
cli ; clear interrupts
lgdt [gdtr] ; load GDT from GDTR (see gdt_32.inc)
call OpenA20Gate ; open the A20 gate
call EnablePMode ; jumps to ProtectedMode
;******************
;* Opens A20 Gate *
;******************
OpenA20Gate:
in al, 0x93 ; switch A20 gate via fast A20 port 92
or al, 2 ; set A20 Gate bit 1
and al, ~1 ; clear INIT_NOW bit
out 0x92, al
ret
;**************************
;* Enables Protected Mode *
;**************************
EnablePMode:
mov eax, cr0
or eax, 1
mov cr0, eax
jmp ProtectedMode ; this works (jumps to label and halts)
;jmp (CODE_DESC-NULL_DESC):ProtectedMode ; => does not work
;jmp 08h:ProtectedMode , => does not work
;***************
;* data fields *
;* &includes *
;***************
%include "gdt_32.inc"
;******************
;* Protected Mode *
;******************
bits 32
ProtectedMode:
;here I want to jump to physical addr 0x8000 (elf64 asm program)
.halt:
hlt
jmp .halt
説明をお寄せいただきありがとうございます...これは私がこれをやっている理由です。そして、x86のリファレンスを読むだけで最初からこれをやったほうが簡単です! Btw:これらのトピックを正確に扱うアドバイスができる素晴らしい本はありますか? –
私は良い本を知らない。インテルとAMDの公式ドキュメントにはすべての情報があります。あなたは簡単に読んですぐに理解できる典型的な本や教科書ではありません(btw、インテルのドキュメントには多くの誤植や間違いがあります)。オンラインで多くの記事やチュートリアルがあります。そして、あなたはいつも実験することができます。または、誰かのコードを見て質問してください。 [alt.os.development](http://groups.google.com/group/alt.os.development/topics)、[comp.lang.asm.x86](http://groups.google .com/group/comp.lang.asm.x86/topics)。 –
あなたのアドバイスありがとうございます!私はそれを見てみましょう! –