參考了百度百科中關于實模式的討論:http://baike.baidu.com/view/404433.htm
及http://hi.baidu.com/toening/blog/item/d8d927d403bdfdc350da4b6d.html
和http://hi.baidu.com/trueailei/blog/item/b8faa413a22c57d7f7039e4d.html
實模式、保護模式、虛擬模式都是X86中的概念。
從尋址方式來說,CPU中的IP(EIP)中存放虛地址,把虛地址轉換到物理地址,各個模式有各自的轉換方式。
實模式下,虛地址到實地址轉換:DS段寄存器左移4位與偏移地址相加,得到物理地址,尋址1M。
保護模式下,虛地址到實地址轉換經過MMU(內存管理單元),也就是分段與分頁機制,尋址4G。
保護有兩層含義:
1、任務間保護:多任務操作系統中,一個任務不能破壞另一個任務的代碼,這是通過內存分頁以及不同任務的內存頁映射到不同物理內存上來實現的。
2、 任務內保護:系統代碼與應用程序代碼雖處于同一地址空間,但系統代碼具有高優先級,應用程序代碼處于低優先級,規定只能高優先級代碼訪問低優先級代碼,這 樣杜絕用戶代碼破壞系統代碼。這是通過段式管理來實現,4G虛擬內存中,代碼數據和堆棧各占有一個段,段是一個獨立有意義的內存單元,有基地址和邊界以及 本段的優先級,windows系統有兩個優先級,Ring0(高優先級)或Ring3(低優先級),系統代碼段和數據段屬于Ring0,不能被用戶代碼 (Ring3)訪問。
實模式:
16bit的8086處理器標志著IntelX86王朝的開始,并且引入了一個重要概念——段。8086處理器地址總線擴展到 20位,但算術邏輯運算單元(ALU)寬度即數據總線卻只有16位,也就是直接運算的指針長度是16位的。為支持1M尋址空間,引入分段的方法。為支持分 段8086CPU設置四個16bit段寄存器:CS、DS、SS、ES,對應于地址總線中的高16位。尋址時,段寄存器*0x10+偏移地址=物理地址。 這樣實現16位內存地址到20位物理地址的轉換,叫“映射”。
(之前在想:為什么每個段最大不超過64K,其實很簡單,因為16位CPU數據線是16位的,所以最多只能用一個16bit數來標識一個偏移量,也就說一個段最大長度是64K)
保護模式:
80286處理器地址總線位數增加到24位,可以訪問16M地址空間。并引入一個新概念——保護模式。這種模式下,內存段的訪 問受到了限制。訪問內存時不能直接從段寄存器獲得段起始地址了,而要經過額外轉換和檢查(從其不能隨意存取數據段)。為與過去兼容,80286內存尋址有 兩種方式:保護模式和實模式。系統啟動時處理器處于實模式,只能訪問1M內存空間,經過處理可以進入保護模式,可訪問16M內存空間,但要從保護模式回到 實模式必須重啟機器。它有個致命缺陷就是80286雖然擴大了尋址空間,但是每個段大小還是64K(因為數據線還是16位的),程序規模仍然受到限制,因 此很快就被80386代替了。
80386是一個32位的CPU。它的地址總線和ALU數據總線都是32位的。尋址能力達到4G。理論上說當數據總線和地址總線寬度一致 時,CPU結構應該簡潔明了,但80386不能做到這點,作為80X86產品系列的一員,80386必須維持那些16位段寄存器的存在,必須支持實模式, 同時還要支持保護模式。Intel選擇在段寄存器基礎上構筑保護模式,保留16位段寄存器。在保護模式下,段范圍達到4G。從80386以后Intel的 CPU經歷了80486、Pentium、Pentium2、Pentium3等型號,但都屬于同一種系統結構的改進與加強,所以把80386以后的處理 器統稱為IA32(32 Bit Intel Architecture)。
深入討論下保護模式:
保護模式與實模式中程序運行的實質是一樣的,都是“CPU執行指令,操作相關數據”。最大的變化是“地址轉換方式”的變化。
這里可以看下兩種模式下地址轉換方式的區別: 在ES存入0x1000,DI存入0xFFFF
實模式:ES:DI = 0x1000 * 0x10 + 0xFFFF = 0x1FFFF,這就是“段基址左移4位加偏移地址”。
保護模式:(注意:0x1000 = 10 0000 0000 0 00 B)ES:DI = GDT全局描述符表中第0x200項描述符給出的段基址 + 0xFFFF。為什么是第0x200項?請看下邊段選擇子(即段值)的結構。
這里ES在兩種模式下都不是真正段地址(實模式下稱"段寄存器",保護模式下稱"選擇子"),都是一種映射,不過映射規則不同而已。
保護模式的基本組成:(圍繞“地址轉換方式”的變化增設了相應機構)
1、數據段
?? 實模式下的各種代碼段、數據段、堆棧段、中斷服務程序仍然存在,這里統稱為“數據段”。
2、描述符
?? 保護模式引入描述符類描述各種數據段,描述符為8個字節(0-7),第5個字節說明描述符類型,類型不同,描述符的結構也不同。
?? 若干描述符集中組成描述符表,描述符表本身也是一種數據段,也使用描述符進行描述。描述符表是一張地址轉換函數表。
3、選擇子
?? 保護模式下,邏輯地址由段選擇子和段內偏移兩部分組成。與實模式相比,保護模式下的段選擇子代替了段值。
?? 段 選擇子有2個BYTE。高13位是描述符索引,第2位TI(Table Indicator)是描述符表指示位,TI=0指示從GTD(全局描述符表)中讀取描述符,TI=1指示從LTD(局部描述符表)中讀取描述符。低2位 是RPL(Request Privilege Level),即進程對段訪問的請求權限,具體可以查閱有關資料。
這里80X86系列引入新的寄存器GDTR和LDTR。
GDTR表示GDT在內存中的段地址和段界限,GDTR是一個48位寄 存器,其中32位表示段地址,16位表示段界限(段最大64K,之前提過描述符表也使用描述符進行描述,因此描述符表最大長度也是64K,里面最多可存放 64K/8Byte=8K個描述符[每個描述符8Byte]。這也是段選擇子中描述符索引占13bit的原因[13b=8192])。
?? 因為GDT不能由GDT本身之內的描述符進行描述定義,所以采用GDTR為GDT這一特殊系統段提供一個偽描述符。
LDTR表示LDT在內存中的位置。因為LDT本身也是一種數據段,它必須有一個描述符存放于GDT中。因此LDTR使用與DS、ES、CS等相同機制,只存放一個“選擇子”,通過查GDT獲得LDT內存地址。
?? LDTR 類似于段寄存器,由程序員可見的16bit寄存器和程序員不可見的高速緩沖寄存器組成。在初始化或切換任務過程中,把描述符對應任務LDT的描述符的選擇 子裝入LDTR,處理器根據LDTR可見部分的選擇子從GDT中取出對應描述符,并把LDT的基地址、界限和屬性等信息保存在LDTR的不可見高速緩沖寄 存器中。隨后對LDT的訪問可根據保存在高速緩沖寄存器中的有關信息進行合法性檢查。
?? LDTR包含當前任務的LDT選擇子。所以裝入到LDTR的選擇子必須確定一個位于GDT中類型為LDT的系統段描述符,即選擇子中的TI=0,且描述符類型字段所表示的類型必須為LDT。
一個多任務操作系統必須有一個GDT,而每一個正在運行的任務(進程)都有一個LDT。可以說保護模式的引進才使得80286以后處理器實現了對 多任務的硬件支持。多任務系統運行中在進程間切換時需要“環境”保護(比如各寄存器值等)。這些“環境”數據構成了一類新的數據段TSS(任務狀態段)。 給TSS段設置描述符(TSS描述符),并把該類描述符放在GDT中(自然不能放在LDT中,80x86也不允許),再加個TR寄存器用于查表。TR(任 務寄存器)是一個起“選擇子”作用的16bit寄存器。任務切換的工作就是將原任務“環境”存入TSS,更新TR,系統將自動查GDT表獲得并裝載新任務 的“環境”,然后找到該任務執行。
段描述符高速緩沖寄存器:
?? 為避免每次存儲器訪問時,都要訪問描述符表獲得對應段描述符,從80286開始每個段寄存器都配有一個高速緩沖寄存器,稱為“描述符高速緩沖寄存器”或“描述符投影寄存器”(shadow register),對于程序員不可見。
?? 每 當一個選擇子裝入某個段寄存器,處理器自動從描述符表中取出相應描述符,把描述符中的信息保存到對應高速緩沖寄存器中。此后對該段訪問時,處理器都使用對 應高速緩沖寄存器中的描述符信息。段描述符高速緩沖寄存器內保存的描述符信息將一直保存到重新把選擇子裝入段寄存器時再更新。程序員盡管不可見段描述符高 速緩沖寄存器,但必須注意到它的存在和它的上述更新時機。例如,在改變了描述符表中的某個當前段的描述符后,也要更新對應的段描述符高速緩沖寄存器的內 容,即使段選擇子未作改變,這可通過重新裝載段寄存器實現。
分頁:
?? 不同程序由不同用戶編寫,而所有這些程序完全可能使用相同地址空間,而程序切換過程一般不包括內存數據的刷新,因為這么做太浪費。因此引入分頁機制才能有效完成對多任務的支持。
?? 分 頁引入的主要目標就是解決不同進程之間發生地址沖突問題。分頁實質就是實現程序內地址到物理地址的映射。用類似GDT的做法:先建立頁表這種數據 段,80x86中使用二級頁表方案,增設一個CR3寄存器用于存放一級頁表(頁目錄)在內存中的地址,CR3共32位,低12位總為零,高20位指示頁目 錄的內存地址,因此頁目錄總是按頁對齊的。CR3作為進程“環境”的一部分在進程切換時被存入TSS數據段中。還有一個相應的缺頁中斷機制及其相關寄存器 CR2(頁故障線性地址寄存器)。
中斷:
?? 80x86(保護模式)與8086(實模式)的中斷機制不一樣。80x86系列為中斷服務提供中斷/陷阱描述符,這些 描述符構成中斷描述符表IDT,并引入一個48bit寄存器IDTR存放IDT的內存地址。理論上IDT表同樣可以有8K項,可是因為80x86只支持 256個中斷,因此IDT實際上最大只能有256項(2K大小,因為所有描述符都是8BYTE)。
總結可得出,保護模式下增加了:
?? 1、寄存器:GDTR、LDTR、IDTR、TR、CR3、CR2
?? 2、數據段:描述符表(GDT、LDT、IDT)、任務數據段(TSS)、頁表(頁目錄、二級頁表)
?? 3、機制:權限檢測(利用選擇子/描述符/頁表項的屬性位)、線性地址到物理地址的映射
=========================================================
實模式:(即實地址訪問模式)它是Intel公司80286及以后的x86(80386,80486和80586等)兼容處理器(CPU)的一種操作模式。實模式被特殊定義為20位地址內存可訪問空間上,這就意味著它的容量是2的20次冪(1M)的可訪問內存空間(物理內存和BIOS-ROM),軟件可通過這些地址直接訪問BIOS程序和外圍硬件。實模式下處理器沒有硬件級的內存保護概念和多道任務的工作模式。但是為了向下兼容,所以80286及以后的x86系列兼容處理器仍然是開機啟動時工作在實模式下。80186和早期的處理器僅有一種操作模式,就是后來我們所定義的實模式。實模式雖然能訪問到1M的地址空間,但是由于BIOS的映射作用(即BIOS占用了部分空間地址資源),所以真正能使用的物理內存空間(內存條),也就是在640k到924k之間。1M地址空間組成是由16位的段地址和16位的段內偏移地址組成的。用公式表示為:物理地址=左移4位的段地址+偏移地址。
286處理器體系結構引入了地址保護模式的概念,處理器能夠對內存及一些其他外圍設備做硬件級的保護設置(保護設置實質上就是屏蔽一些地址的訪問)。使用這些新的特性,然而必不可少一些額外的在80186及以前處理器沒有的操作規程。自從最初的x86微處理器規格以后,它對程序開發完全向下兼容,80286芯片被制作成啟動時繼承了以前版本芯片的特性,工作在實模式下,在這種模式下實際上是關閉了新的保護功能特性,因此能使以往的軟件繼續工作在新的芯片下。直到今天,甚至最新的x86處理器都是在計算機加電啟動時都是工作在實模式下,它能運行為以前處理器芯片寫的程序.
DOS操作系統(例如MS-DOS,DR-DOS)工作在實模式下,微軟Windows早期的版本(它本質上是運行在DOS上的圖形用戶界面應用程序,實際上本身并不是一個操作系統)也是運行在實模式下,直到Windows3.0,它運行期間既有實模式又有保護模式,所以說它是一種混合模式工作。它的保護模式運行有兩種不同意義(因為80286并沒有完全地實現80386及以后的保護模式功能):
1〉“標準保護模式”:這就是程序運行在保護模式下;
2〉“虛擬保護模式(實質上還是實模式,是實模式上模擬的保護模式)”:它也使用32位地址尋址方式。Windows3.1徹底刪除了對實模式的支持。在80286處理器芯片以后,Windows3.1成為主流操作系統(Windows/80286不是主流產品)。目前差不多所有的X86系列處理器操作系統(Linux,Windows95 and later,OS/2等)都是在啟動時進行處理器設置而進入保護模式的。
實模式工作機理:
1> 對于8086/8088來說計算實際地址是用絕對地址對1M求模。8086的地址線的物理結構:20根,也就是它可以物理尋址的內存范圍為2^20個字節,即1 M空間,但由于8086/8088所使用的寄存器都是16位,能夠表示的地址范圍只有0-64K,這和1M地址空間來比較也太小了,所以為了在8086/8088下能夠訪問1M內存,Intel采取了分段尋址的模式:16位段基地址:16位偏移EA。其絕對地址計算方法為:16位基地址左移4位+16位偏移=20位地址。比如:DS=1000H EA=FFFFH 那么絕對地址就為:10000H + 0FFFFH = 1FFFFH 地址單元。通過這種方法來實現使用16位寄存器訪問1M的地址空間,這種技術是處理器內部實現的,通過上述分段技術模式,能夠表示的最大內存為:FFFFh: FFFFh=FFFF0h+FFFFh=10FFEFh=1M+64K-16Bytes(1M多余出來的部分被稱做高端內存區HMA)。但8086/8088只有20位地址線,只能夠訪問1M地址范圍的數據,所以如果訪問100000h~10FFEFh之間的內存(大于1M空間),則必須有第21根地址線來參與尋址(8086/8088沒有)。因此,當程序員給出超過1M(100000H-10FFEFH)的地址時,因為邏輯上正常,系統并不認為其訪問越界而產生異常,而是自動從0開始計算,也就是說系統計算實際地址的時候是按照對1M求模的方式進行的,這種技術被稱為wrap-around。
2> 對于80286或以上的CPU通過A20 GATE來控制A20地址線。 技術發展到了80286,雖然系統的地址總線由原來的20根發展為24根,這樣能夠訪問的內存可以達到2^24=16M,但是Intel在設計80286時提出的目標是向下兼容,所以在實模式下,系統所表現的行為應該和8086/8088所表現的完全一樣,也就是說,在實模式下,80386以及后續系列應該和8086/8088完全兼容仍然使用A20地址線。所以說80286芯片存在一個BUG:它開設A20地址線。如果程序員訪問100000H-10FFEFH之間的內存,系統將實際訪問這塊內存(沒有wrap-around技術),而不是象8086/8088一樣從0開始。我們來看一副圖:
<!--[if !vml]-->??? ?? 
????? 為了解決上述兼容性問題,IBM使用鍵盤控制器上剩余的一些輸出線來管理第21根地址線(從0開始數是第20根)的有效性,被稱為A20 Gate:
????? 1> 如果A20 Gate被打開,則當程序員給出100000H-10FFEFH之間的地址的時候,系統將真正訪問這塊內存區域;
????? 2 如果A20 Gate被禁止,則當程序員給出100000H-10FFEFH之間的地址的時候,系統仍然使用8086/8088的方式即取模方式(8086仿真)。絕大多數IBM PC兼容機默認的A20 Gate是被禁止的。現在許多新型PC上存在直接通過BIOS功能調用來控制A20 Gate的功能。
????? 上面所述的內存訪問模式都是實模式,在80286以及更高系列的PC中,即使A20 Gate被打開,在實模式下所能夠訪問的內存最大也只能為10FFEFH,盡管它們的地址總線所能夠訪問的能力都大大超過這個限制。為了能夠訪問10FFEFH以上的內存,則必須進入保護模式。
保護模式:經常縮寫為p-mode,在Intel iAPX 286程序員參考手冊中(iAPX 286是Intel 80286的另一種叫法)它又被稱作為虛擬地址保護模式。經管在Intel 80286手冊中已經提出了虛地址保護模式,但實際上它只是一個指引,真正的32位地址出現在Intel 80386上。保護模式本身是80286及以后兼容處理器序列之后產成的一種操作模式,它具有許多特性設計為提高系統的多道任務和系統的穩定性。例如內存的保護,分頁機制和硬件虛擬存儲的支持。現代多數的x86處理器操作系統都運行在保護模式下,包括Linux, Free BSD, 和Windows 3.0(它也運行在實模式下,為了和Windows 2.x應用程序兼容)及以后的版本。
80286及以后的處理器另一種工作模式是實模式(僅當系統啟動的一瞬間),本著向下兼容的原則屏蔽保護模式特性,從而容許老的軟件能夠運行在新的芯片上。作為一個設計規范,所有的x86系列處理器,除嵌入式Intel80387之外,都是系統啟動工作在實模式下,確保遺留下的操作系統向下兼容。它們都必須被啟動程序(操作系統程序最初運行代碼)重新設置而相應進入保護模式的,在這之前任何的保護模式特性都是無效的。在現代計算機中,這種匹配進入保護模式是操作系統啟動時最前沿的動作之一。
在被調停的多道任務程序中,它可以從新工作在實模式下是相當可能的。保護模式的特性是阻止被其他任務或系統內核破壞已經不健全的程序的運行,保護模式也有對硬件的支持,例如中斷運行程序,移動運行進程文檔到另一個進程和置空多任務的保護功能。
386及以后系列處理器不僅具有保護模式又具有32位寄存器,結果導致了處理功能的混亂,因為80286雖然支持保護模式,但是它的寄存器都是16位的,它是通過自身程序設定而模擬出的32位,并非32位寄存器處理。歸咎于這種混亂現象,它促使Windows/386及以后的版本徹底拋棄80286的虛擬保護模式,以后保護模式的操作系統都是運行在80386以上,不再運行在80286(盡管80286模式支持保護模式),所以說80286是一個過渡芯片,它是一個過渡產品。
盡管286和386處理器能夠實現保護模式和兼容以前的版本,但是內存的1M以上空間還是不易存取,由于內存地址的回繞,IBM PC XT (現以廢棄)設計一種模擬系統,它能過欺騙手段訪問到1M以上的地址空間,就是開通了A20地址線。在保護模式里,前32個中斷為處理器異常預留,例如,中斷0D(十進制13)常規保護故障和中斷00是除數為零異常。
如果要訪問更多的內存,則必須進入保護模式,那么,在保護模式下,A20 Gate對于內存訪問有什么影響呢?
????? 為了搞清楚這一點,我們先來看一看A20的工作原理。A20,從它的名字就可以看出來,其實它就是對于A20(從0開始數)的特殊處理(也就是對第21根地址線的處理)。如果A20 Gate被禁止,對于80286來說,其地址為24根地址線,其地址表示為EFFFFF;對于80386極其隨后的32根地址線芯片來說,其地址表示為FFEFFFFF。這種表示的意思是:

??? 1>如果A20 Gate被禁止。則其第A20在CPU做地址訪問的時候是無效的,永遠只能被作為0。所以,在保護模式下,如果A20 Gate被禁止,則可以訪問的內存只能是奇數1M段,即1M,3M,5M…,也就是00000-FFFFF, 200000-2FFFFF,300000-3FFFFF…
????? 2如果A20 Gate被打開。則其第20-bit是有效的,其值既可以是0,又可以是1。那么就可以使A20線傳遞實際的地址信號。如果A20 Gate被打開,則可以訪問的內存則是連續的。
實模式和保護模式的區別:從表面上看,保護模式和實模式并沒有太大的區別,二者都使用了內存段、中斷和設備驅動來處理硬件,但二者有很多不同之處。我們知道,在實模式中內存被劃分成段,每個段的大小為64KB,而這樣的段地址可以用16位來表示。內存段的處理是通過和段寄存器相關聯的內部機制來處理的,這些段寄存器(CS、DS、 SS和ES)的內容形成了物理地址的一部分。具體來說,最終的物理地址是由16位的段地址和16位的段內偏移地址組成的。用公式表示為:物理地址=左移4位的段地址+偏移地址。
在保護模式下,段是通過一系列被稱之為“描述符表”的表所定義的。段寄存器存儲的是指向這些表的指針。用于定義內存段的表有兩種:全局描述符表(GDT) 和局部描述符表(LDT)。GDT是一個段描述符數組,其中包含所有應用程序都可以使用的基本描述符。在實模式中,段長是固定的(為64KB),而在保護模式中,段長是可變的,其最大可達4GB。LDT也是段描述符的一個數組。與GDT不同,LDT是一個段,其中存放的是局部的、不需要全局共享的段描述符。每一個操作系統都必須定義一個GDT,而每一個正在運行的任務都會有一個相應的LDT。每一個描述符的長度是8個字節,格式如圖3所示。當段寄存器被加載的時候,段基地址就會從相應的表入口獲得。描述符的內容會被存儲在一個程序員不可見的影像寄存器(shadow register)之中,以便下一次同一個段可以使用該信息而不用每次都到表中提取。物理地址由16位或者32位的偏移加上影像寄存器中的基址組成。實模式和保護模式的不同可以從下圖很清楚地看出來。

??????????????? 實模式下尋址方式
??? <!--[if !vml]-->
????????????????? ?? 保護模式下尋址方式