我目前正在使用x86 Assember來提高我的低級編程技能。目前,我在32位保護模式下尋址方案遇到了一些問題。彙編程序跳轉到GDT保護模式
的情況如下:
我在0x7e0加載的程序將CPU切換到保護模式,並跳轉到在代碼中根據標籤:
[...]
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現在處於ProtectedMode而不是RealMode,因此尋址模式不同。 ProtectedMode使用描述符選擇器在描述符表中查找基地址和限制,以添加給定的偏移量並檢索物理地址(據我所知)。因此,在進入ProtectedMode之前,有必要安裝GDT。
礦正在尋找類似如下:
%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註冊通過
lgdt [gdtr]
我不明白到目前爲止,我怎麼現在跳到物理在ProtectedMode中使用GDT地址0x8000?我的第一個想法是選擇應該指向0x7e00(當前程序被加載)的代碼描述符(CODE_DESC),並使用必要的偏移量來達到0x8000(512字節),從而產生跳轉指令:
jmp CODE_DESC:0x200
但這不起作用。
jmp 0x7e0:0x200
也不管用...
你有任何想法,我在這裏失蹤?也許我不明白32位ProtectedMode尋址方案和GDT的用法。
[編輯]完整代碼:
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引用時,這並不是那麼簡單:)!順便說一句:有什麼偉大的書,你可以建議,處理完全這些類型的話題? – 2012-02-05 04:29:23
我不認識好書。英特爾和AMD的官方文檔包含了所有的信息,它不是一種您可以輕鬆閱讀並且立即理解所有內容的典型書籍或教科書(順便提一句,英特爾文檔中存在很多錯別字和偶爾的錯誤)。網上有很多文章和教程。你可以隨時做實驗。或者查看某人的代碼並提出問題。查看以下羣組:[alt.os.development](http://groups.google.com/group/alt.os.development/topics),[comp.lang.asm.x86](http://groups.google的.com /組/ comp.lang.asm.x86 /主題)。 – 2012-02-05 05:02:03
感謝您的諮詢!我會看看那個! – 2012-02-05 07:08:42