1. 程式人生 > >真實模式和保護模式

真實模式和保護模式

       從80386開始,CPU有三種工作模式:真實模式、保護模式和虛擬8086模式。80286開始的CPU引入保護模式,實際上,真實模式概念是在保護模式推出之後為了區別保護模式之前的8086CPU工作模式才有的,在8086時代CPU工作模式只有一種,自然沒有真實模式之說。真實模式有著先天的缺陷(下文詳述),但出於向上相容的考慮,現代CPU仍然保持著對16位操縱模式的相容。

       所謂工作模式,是指CPU的定址方式、暫存器大小、指令用法和記憶體佈局等。

真實模式

       真實模式的“實”體現在程式中用到的地址都是真實的實體地址,“段基址:段內偏移地址”產生的邏輯地址就是實體地址,即程式設計師可見的地址完全是真實的記憶體地址。

        在真實模式下,記憶體定址方式和8086相同,由16位段暫存器的內容乘以16(左移4位)作為段基址,加上16位段偏移地址形成20位的實體地址,最大定址空間1MB,最大分段64KB。可以使用32位指令,即32位的x86 CPU也可以相容真實模式,此時的真實模式相當於高速的8086(32位CPU的真實模式可以使用32位下的資源)。在32位CPU下,系統復位或加電時都是以真實模式啟動,然後再切換為保護模式。在真實模式下,所有的段都是可以讀、寫和可執行的。

       下圖是真實模式下的記憶體訪問模型:

       8086CPU的真實模式開創性地提出了地址分段的概念,改變了在它之前的CPU只能“硬編碼”,程式無法重定位的缺點。然而真實模式還是有很多缺陷,其中最主要的是真實模式的安全隱患。在真實模式下,使用者程式和作業系統擁有同等權利,因為真實模式下沒有特權級。此外,程式可以隨意修改自己的段基址,加上真實模式下對地址的訪問就是實實在在的實體地址,因此程式可以隨意修改任意實體地址,甚至包括作業系統所在的記憶體,這給作業系統帶來極大的安全問題。

保護模式

       儘管在Intel 80286手冊中已經提出了保護模式,但實際上它只是一個指引。80286雖然有了保護模式但其依然是16位的CPU,其通用暫存器還是16位寬,只不過其地址線由20位變成了26位,即定址空間擴大到了16MB(但受限於暫存器位寬,單個暫存器的定址空間仍然為64KB)。80286只是一個“過渡”產品,很快就被淘汰。

       真正的32位地址出現在Intel 80386上,它的地址匯流排和暫存器都是32位的,因此其單暫存器的定址空間擴大到了4GB——在當時甚至其後的數年,僅通過段內偏移地址都足以訪問記憶體的任意角落,這也開啟了“平坦模式”的時代。

       保護模式本身是80286及以後相容處理器序列之後產成的一種操作模式,它具有許多特性設計為提高系統的多道任務和系統的安全性及穩定性——例如記憶體的保護,分頁機制和硬體虛擬儲存的支援。現代多數的x86處理器作業系統都執行在保護模式下,包括Linux, Free BSD, 和Windows3.0(它也執行在真實模式下,為了和Windows 2.x應用程式相容)及以後的版本。 

       在保護模式中,記憶體的管理模式分為兩種——段模式和頁模式。其中頁模式也是基於段模式的。也就是說,保護模式的記憶體管理模式事實上是:純段模式和段頁式。進一步說,段模式是必不可少的,而頁模式則是可選的——如果使用頁模式,則是段頁式,否則這是純段模式。

       為了改進真實模式下記憶體訪問的不安全性,保護模式給記憶體段添加了段屬性來限制使用者程式對記憶體的操作許可權。保護模式引入了全域性描述符表(Global Description Table,GDT),GDT的表項是描述段型別屬性的資料結構——段描述符。GDT中的每一個段描述符都描述了一個記憶體段的幾本屬性,如段基址、段界限、型別、DPL等等。

       正是由於以上概念的提出,使得“段地址:段內偏移地址”的訪問策略從真實模式下對實體地址的直接對映變成了保護模式下對GDT或LDT的間接對映(如下圖所示)。段屬性的加入讓使用者程式對記憶體的訪問不再“為所欲為”。