複製鏈接
請複製以下鏈接發送給好友

實模式

鎖定
CPU復位(reset)或加電(power on)的時候以實模式啓動,處理器以實模式工作。在實模式下,內存尋址方式和8086相同,由16位段寄存器的內容乘以16(10H)當做段基地址,加上16位偏移地址形成20位的物理地址,最大尋址空間1MB,最大分段64KB。可以使用32位指令。32位的x86 CPU用做高速的8086。在實模式下,所有的段都是可以讀、寫和可執行的。
286架構導入保護模式,允許硬件等級的存儲器保護。然而要使用這些新的特色,需要額外先前不需要的軟件指令。由於x86微處理機主要的設計規格,是能夠完全地向前兼容於針對先前所有x86芯片所撰寫的軟件,因此286芯片的開機是處於'實模式'—也就是關閉新的存儲器保護特性的模式,所以可以運行針對舊的微處理器所設計的軟件。到現在為止,即使最新的x86 CPU一開始在電源打開處於實模式下,也能夠運行針對先前任何芯片所撰寫的軟件.
中文名
實時模式
中文縮寫
實模式
對應概念
保護模式
領    域
計算機操作系統.彙編語言

實模式基本概念

保護模式下的實模式
保護模式:尋址採用32位段和偏移量,最大尋址空間4GB,最大分段4GB (Pentium Pre及以後為64GB)。在保護模式下CPU可以進入虛擬8086方式,這是在保護模式下的實模式程序運行環境。

實模式運行命令

程序運行的實質是什麼?其實很簡單,就是指令的執行,顯然CPU是指令得以執行的硬件保障,那麼CPU如何知道指令在什麼地方呢?
80x86系列是使用CS寄存器配合IP寄存器來通知CPU指令在內存中的位置.
程序指令在執行過程中一般還需要有各種數據,80x86系列有DS、ES、FS、GS、SS等用於指示不同用途的數據段在內存中的位置。
程序可能需要調用系統的服務子程序,80x86系列使用中斷機制來實現系統服務
總的來説,這些就是實模式下一個程序運行所需的主要內容(其它如跳轉、返回、端口操作等相對來説比較次要。)

實模式保護模式

保護模式---從程序運行説起
無論實模式還是保護模式,根本的問題還是程序如何在其中運行。
因此我們在學習保護模式時應該時刻圍繞這個問題來思考。和實模式下一樣,保護模式下程序運行的實質仍是“CPU執行指令,操作相關數據”,因此實模式下的各種代碼段數據段堆棧段中斷服務程序仍然存在,且功能、作用不變。
那麼保護模式下最大的變化是什麼呢?答案可能因人而異,我的答案是“地址轉換方式”變化最大。

實模式方式比較

先看一下實模式下的地址轉換方式,假設我們在ES中存入0x1000,DI中存入0xFFFF,那麼ES:DI=0x1000*0x10+0xFFFF=0x1FFFF,這就是眾所周知的“左移4位加偏移”。
那麼如果在保護模式下呢?假設上面的數據不變ES=0x1000,DI=0xFFFF,現在ES:DI等於什麼呢?
公式如下:(注:0x1000=1000000000000b= 10 0000 0000 0 00)ES:DI=全局描述符表中第0x200項描述符給出的段基址+0xFFFF
現在比較一下,好象是不一樣。再仔細看看,又好象沒什麼區別!
為什麼説沒什麼區別,因為我的想法是,既然ES中的內容都不是真正的段地址,憑什麼實模式下稱ES為“段寄存器”,而到了保護模式就説是“選擇子”?你覺得呢?
其實它們都是一種映射,只是映射規則不同而已:在實模式下這個“地址轉換方式”是“左移4位”;在保護模式下是“查全局/局部描述表”。前者是系統定義的映射方式,後者是用户自定義的轉換方式。而它影響的都是“shadow register”從函數的觀點來看,前者是表達式函數,後者是列舉式函數:
實模式: F(es-->segment)={segment |segment=es*0x10}
保護模式:F(es-->segment)={segment |(es,segment)∈GDT/LDT}
其中GDT、LDT分別表示全局描述符表和局部描述符表。

實模式組成部分

保護模式最基本的組成部分是圍繞着“地址轉換方式”的變化增設了相應的機構。
1、數據段
前面説過,實模式下的各種代碼段、數據段、堆棧段、中斷服務程序仍然存在,我將它們統稱為“數據段”,本文從此向下凡提到數據段都是使用這個定義。
2、描述符
保護模式下引入描述符來描述各種數據段,所有的描述符均為8個字節(0-7),由第5個字節説明描述符的類型,類型不同,描述符的結構也有所不同。
若干個描述符集中在一起組成描述符表,而描述符表本身也是一種數據段,也使用描述符進行描述。從現在起,“地址轉換”由描述符表來完成,從這個意義上説,描述符表是一張地址轉換函數表。
3、選擇子
選擇子是一個2字節的數,共16位,最低2位表示RPL,第3位表示查表是利用GDT(全局描述符表)還是LDT(局部描述符表)進行,最高13位給出了所需的描述符在描述符表中的地址。(注:13位正好足夠尋址8K項)有了以上三個概念之後可以進一步工作了,現在程序的運行與實模式下完全一樣!!!各段寄存器仍然給出一個“段值”,只是這個“假段值”到真正的段地址的轉換不再是“左移4位”,而是利用描述符表來完成。但現在出現一個新的問題是:
系統如何知道GDT/LDT在內存中的位置呢?
為了解決這個問題,顯然需要引入新的寄存器用於指示GDT/LDT在內存中的位置。在80x86系列中引入了兩個新寄存器GDTR和LDTR,其中GDTR用於表示GDT在內存中的段地址和段限(就是表的大小),因此GDTR是一個48位的寄存器,其中32位表示段地址,16位表示段限(最大64K,每個描述符8字節,故最多有64K/8=8K個描述符)。LDTR用於表示LDT在內存中的位置,但是因為LDT本身也是一種數據段,它必須有一個描述符,且該描述符必須放在GDT中,因此LDTR使用了與DS、ES、CS等相同的機制,其中只存放一個“選擇子”,通過查GDT表獲得LDT的真正內存地址。對了,還有中斷要考慮,在80x86系列中為中斷服務提供中斷/陷阱描述符,這些描述符構成中斷描述符表(IDT),並引入一個48位的全地址寄存器存放IDT的內存地址。理論上IDT表同樣可以有8K項,可是因為80x86只支持256箇中斷,因此IDT實際上最大隻能有256項(2K大小)。

實模式問題總結

實模式基本問題

前面介紹了保護模式的基本問題,也是核心問題,解決了上面的問題,程序就可以在保護模式下運行了。
但眾所周知80286以後在保護模式下實現了對多任務的硬件支持。我的第一反應是:為什麼不在實模式下支持多任務,是不能還是不願?
思考之後,我的答案是:實模式下能實現多任務。
因為多任務的關鍵是有了描述符,可以給出關於數據段的額外描述,如權限等,進而在這些附加信息的基礎上進行相應的控制,而實模式下缺乏描述符,但假設我們規定各段的前2個字節或若干字節用於描述段的附加屬性,我覺得和使用描述符這樣的機制沒有本質區別,如果再附加其他機制...基於上述考慮,我更傾向於認為任務是獨立於保護模式之外的功能。
下面我們來分析一下任務。任務的實質是什麼呢?很簡單,就是程序嘛!!
所謂任務的切換其實就是程序的切換!!
現在問題明朗了。實模式下程序一個接一個運行,因此程序運行的“環境”不必保存;保護模式下可能一個程序在運行過程中被暫停,轉而執行下一個程序,我們要做什麼?很容易想到保存程序運行的環境就行了(想想遊戲程序的保存進度功能),比如各寄存器的值等。
顯然這些“環境”數據構成了一類新的數據段(即TSS)。延用前面的思路,
給這類數據段設置描述符(TSS描述符),將該類描述符放在GDT中(不能放在LDT中,因為80x86不允許:)),最後再加一個TR寄存器用於查表。TR是一個起“選擇子”作用的寄存器,16位。
好了,任務切換的基本工作就是將原任務的“環境”存入TSS數據段,更新TR寄存器,系統將自動查GDT表獲得並裝載新任務的“環境”,然後轉到新任務執行。

實模式附加要求

為什麼叫附加要求,因為現在任務還不能很好地工作。前面説過,任務實質上是程序,不同的程序是由不同的用户寫的,所有這些程序完全可能使用相同的地址空間,而任務的切換過程一般不會包括內存數據的刷新,不是不可能,而是如果那樣做太浪費了。因此必須引入分頁機制才可能有效地完成對多任務的支持。
分頁的實質就是實現程序內地址到物理地址的映射,這也是一個“地址轉換”機制,同樣可以使用前面的方案(即類似GDT的做法):首先建立頁表這樣一種數據段,在80x86中使用二級頁表方案,增設一個CR3寄存器用於存放一級頁表(又稱為頁目錄)在內存中的地址,CR3共32位,其低12位總是為零,高20位指示頁目錄的內存地址,因此頁目錄總是按頁對齊的。CR3作為任務“環境”的一部分在任務切換時被存入TSS數據段中。
當然還得有相應的缺頁中斷機制及其相關寄存器CR2(頁故障線性地址寄存器)。
保護模式下增加了什麼?
1、寄存器 GDR LDR IDR TR CR3
2、數據段 描述符表(GDT LDT) 任務數據段(TSS) 頁表(頁目錄 二級頁表)
3、機制 權限檢測(利用選擇子/描述符/頁表項的屬性位)
線性地址到物理地址的映射

實模式常用名詞

前面內容中出現過的不再解釋。
1、RPL 選擇子當中的權限位確定的權限
2、CPL 特指CS中的選擇子當中的權限位確定的權限
3、EPL EPL=Max(RPL,CPL),即RPL和CPL中數值較大的,或説權限等級較小的
4、DPL 描述符中的權限位確定的權限
5、PL 泛指以上4種特權級
6、任務特權 =CPL
7、I/O特權 由EFLAGS寄存器的位13、14確定的權限
8、一致代碼段 一種特殊的代碼段,它在CPL>=DPL時允許訪問
正常的代碼段在CPL=DPL RPL<=DPL時才允許訪問