小華的部落格: Flat Memory Mode

搜尋此網誌

網頁

星期三, 12月 19, 2007

Flat Memory Mode

最近在逛ㄧ些網站看到下面這篇文章,在講所謂的Flat Memory Mode,由於資料說明的很詳細,所以就收集文章在自己部落格中,有興趣的朋友可以去原作者部落格看這篇的完整文章,以下是轉貼部份內容。

原文章出處:http://w3tony.blogspot.com/2006/04/flat-real-mode_114619442075796383.html

~以下是轉貼內容~
Flat real mode 或者是 unreal Mode,名詞很多,不過主要的用處都一樣,在 Real Mode 存取超過 1MB 以上的記憶體空間,下面就來介紹怎麼進入 Flat Real Mode。

要能夠使用 32bit 的 segment,首先需要進入保護模式,最簡單的方法是:

cli
mov eax,cr0
or al,1
mov cr0,eax
sti

cli 的目的是將中斷遮蔽,避免臨時的中斷服務打斷我們的工作,透過設定 CR0 的 PE bit 就可以進入 Protected Mode,接下來我們需要 descriptor table 才能夠將 segment limit 從 64K 換成 4G,

DataSel = 8
GDT dw 4 dup(0) ; NULL descriptor
dw 0ffffh,0ffh,9200h,8fh ;Data segment descriptor
GDT_ptr label fword
dw offset GDTptr-1-offset GDT
dd offset GDT

DataSel 指 Data segment entry 的 selector,設定為 8 表示我們的 entry 是在 NULL Descriptor 的下一個位置,GDT_ptr 用來存放 GDT Table 的長度以及 GDT Table 的 Linear Address,再來我們要將 GDT Table 載入到 gdt 暫存器,方法如下

mov ax,cs
mov ds,ax
movzx eax,ax
shl eax,4
add dword ptr ds:GDT_ptr+2,eax ;將 GDT 的 Linear Address 存入 GDT_ptr
lgdt fword ptr ds:GDT_ptr ;載入 GDT table

cli
mov eax,cr0
or al,1
mov cr0,eax
sti

然後需要一個 jump 的動作,目的是清除 instruction queue 的 real mode instruction:

mov ax,cs
mov ds,ax
movzx eax,ax
shl eax,4
add dword ptr ds:GDT_ptr+2,eax ;將 GDT 的 Linear Address 存入 GDT_ptr
lgdt fword ptr ds:GDT_ptr ;載入 GDT table
cli
mov eax,cr0
or al,1
mov cr0,eax
sti
jmp short pmode ; Clear the execution pipe
pmode:
mov ax,DataSel ; 進入保護模式
mov ds,ax ; 設定 selector limits 為 4 GB
mov es,ax
mov fs,ax
mov gs,ax

現在我們已經進入 Protected Mode,不過這樣只是單純的保護模式,還不是 Flat Real Mode,所以我們還需要一個步驟,返回 Real Mode,方法如下:

mov ax,cs
mov ds,ax
movzx eax,ax
shl eax,4
add dword ptr ds:GDT_ptr+2,eax ;將 GDT 的 Linear Address 存入 GDT_ptr
lgdt fword ptr ds:GDT_ptr ;載入 GDT table
cli
mov eax,cr0
or al,1
mov cr0,eax
sti
jmp short pmode ; Clear the execution pipe
pmode:
mov ax,DataSel ; 進入保護模式
mov ds,ax ; 設定 selector limits 為 4 GB
mov es,ax
mov fs,ax
mov gs,ax
jmp short Real_mode
Real_mode:
clc;我們已經返回 real mode了並且將 carry flag 清除,通常這代表正確執行

sti ;解除中斷遮蔽
ret

進行到這,我們已經將 fs 與 gs 設定成 4G 範圍的 segment,試試看使用
mov eax, 6400000H
mov edi, eax
mov eax, dword ptr gs:[edi]

能不能讀取到 100MB 的記憶體內容,是不是很有趣?Flat real mode 的應用很多,不過有個很大的缺點,執行的 code 還是只能放在 1MB 的範圍,只有 data 才能存取 4GB 的空間。往後我還會繼續介紹怎麼返回真實模式,有許多注意事項是常常被人乎略的,尤其是當我們需要重複進入跟退出保護模式時,很容易破壞暫存器的設定,例如 SS:SP 就是最常忘記的地方,下次有機會再繼續討論這個部份。

延伸閱讀:
Flat real mode
http://www.df.lth.se/~john_e/gems/gem0022.html
Flat real mode interface http://www.programmersheaven.com/zone5/cat19/1365.htm

沒有留言: