當前位置:文思屋>學習教育>畢業論文>

在DOS真實模式下直接存取4GB記憶體

文思屋 人氣:8.58K
在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上電也整個程式碼段暫存器是這樣的: