- 相關推薦
在DOS實模式下直接存取4GB內存
作為軟件開發人員,大多數對于保護模式都感到神秘和不易理解。本人在開發32位微內核搶占式多線程操作系統過程中,深入了解到CPU的地址機理,在這里將分析CPU的工作原理,解開保護模式的神秘面紗,讀者將會發現保護模式其實與實模式一樣簡單和易于控制。在此基礎上用四五十行C語言程序做到進出保護模式和在實模式之下直接訪問整個4GB內存空間。
雖然有許多書籍對保護模式作解釋,但沒有一本能簡單明了地解釋清楚,冗長煩雜的術語讓人看著想打瞌睡,甚至還有許多用匯編寫的(可能根本不能運行的)保護模式試驗程序,事實上用C語言本身就可以做保護模式的進出工作。
我們可能知道CPU上電后從ROM中的BIOS開始運行,而Intel文檔卻說80x86CUP上電總是從最高內存下16字節開始執行,那么BIOS是處在內存的最頂端64K(FFFF0000H)還是1M之下的64K(F0000H)處呢?事實上在這兩個地方都同時出現(可用后面存取4GB內存的程序驗證)。
為什么?為了弄清楚以上問題,首先要了解CPU是如何處理物理地址的?真的是在實模式下用段寄存器左移4位與偏移量相加,在保護模式下用段描述符中的基地址加偏移量而兩者是毫無關聯的嗎?答案是兩者其實是一樣的。當Intel把80286推出時其地址空間變成了24位,從8086的20位到24位,十分自然地要加大段寄存器才行,實際上它們都被加大了,只是由于保護的原因加大的部分沒有被程序看見,到了80386之后地址又從24位加大到32位(80386SX是24位)。整個段寄存器如下圖所示:
@@12A08400.GIF;圖1@@
在8086中CPU只有“看得見部分”,從而也直接參與了地址形成運算,但在80286之后,在“看不見部分”中已經包含了地址值,“看得見部分”就退化為只是一個標號再也不用參與地址形成運算了。地址的形成總是從“不可看見部分”取出基址值與偏移相加形成地址。也就是說在實模式下當一個段寄存器被裝入一個值時,“看不見部分”的界限被設成FFFFH,基址部分才是要裝入值左移4位,屬性部分設成16位0特權級。這個過程與保護模式時裝入一個段存器是同理的,只是保護模式的“不可見部分”是從描述表中取值,而實模式是一套固定的過程。
對于CPU在形成地址時,是沒有實模式與保護模式之分的,它只管用基址(“不可見部分”)去加上偏移量。實模式與保護模式的差別實際上只是保護處理部件是否工作得更精確而已,比如不允許代碼段的寫入。實模式下的段寄存裝入有固定的形成辦法從而也就不需要保護模式的“描述符”了,因此保持了與8086/8088的兼容性。而“描述符”也只是為了裝入段寄存器的“不可見部分”而設的。
從上面的“整個段寄存器”可見CPU的地址形成與“看得見部分”的當前值毫無關系,這也解釋了為什么在剛進入保護模式時后面的代碼依然被正確地運行而這時代碼段寄存器CS的值卻還是進入保護模式前的實模式值,或者從保護模式回到實模式時代碼段CS被改變之前程序是正常地工作,而不會“突變”到CS左移4位的地址上去,比如在保護模式時CS是08H的選擇器,到了實模式時CS還是08H但地址不會突然變成80H加上偏段量中去。因為地址的形成不理會段寄存器“看得見部分”的當前值,這一個值只是在被裝入時對CPU有用。
地址的形成與CPU的工作模式無關,也就是說實模式與0特權級保護模式不分頁時是一模一樣的。明白了這一機理,在實模式下一樣可以處理通常被認為只有在保護模式才能做的事,比如訪問整個機器的內存。可以不必理會保護模式下的眾多術語,或者更易于理解,如選擇器就是“看得見部分”,描述符是為了裝入“不可見部分”而設的。
作為驗證CPU的這種機理,這里寫了一個實模式下訪問4GB內存的C程序。有一些書籍也介紹有同樣功能的匯編程序,但它們都錯誤地認為是利用80386芯片的設計疏漏。實際上Intel本身就在使用這種辦法,使得CPU上電時能從FFFFFFF0H處開始第一條指令,這種技術在286之后的每一臺機器每一次冷啟動時都使用,只是我們不知道罷了。CPU上電也整個代碼段寄存器是這樣的:
@@12A08401.GIF;圖2@@
EIP=0000FFF0H
這樣CS∶EIP形成了FFFFFFF0H的物理地址,當CPU進行一次遠跳轉重新裝入CS時,基址就變了。
為了訪問4G內存空間,必須有
[1] [2] [3] [4]
【在DOS實模式下直接存取4GB內存】相關文章:
DOS命令04-29
網絡模式下的編輯流程04-26
內存·什么是內存電壓04-26
數控實訓教學模式探討04-29
互動教學模式下的詞匯教學05-02
新課標背景下的教學模式構建04-28
網絡環境下教學模式探索05-01
企業訂單模式下駕駛臺資源管理實訓過程設計04-28
DOS的特點電腦資料11-01
故障模式下的空間交會防撞設計04-27