保護模式(英語:Protected Mode,或有時簡寫為 pmode)是一種80286系列和之後的x86相容CPU的操作模式。保護模式有一些新的特性,如記憶體保護分頁系統以及硬件支援的虛擬記憶體,能夠增強多工處理和系統穩定度。現今大部分的x86作業系統都在保護模式下運行,包含LinuxFreeBSD、以及微軟Windows 2.0和之後版本。

另外一種286和其之後CPU的操作模式是真實模式,這是一種向前相容且關閉了保護模式這些特性的CPU操作模式,用來讓新的晶片可以執行舊的軟件。所有的x86 CPU都是在真實模式下開機,來確保傳統作業系統的相容性。為了使用保護模式的特性,要由程式主動地切換到保護模式。在現今的電腦上,這種切換通常是作業系統在開機時候完成的第一件工作。當CPU在保護模式下運行時,可以使用虛擬86模式來執行為真實模式設計的程式碼。

儘管用軟件的方式也有某些可能在真實模式的系統下使用多工,但保護模式下記憶體保護的特色,可以避免有問題的程式破壞其他工作或是作業系統核心所擁有的記憶體。保護模式也有中斷正在執行程式的硬件支援,可以實現先佔式多工

大部分可以使用保護模式的CPU也擁有32位元暫存器的特性(例如80386系列和其後任何的晶片),匯入了融合保護模式而成為32位元處理的概念。80286晶片雖有支援保護模式,但是仍然只有16位元暫存器。Windows 2.0和之後版本中的保護模式增強稱為"386增強模式",是因為他們除了保護模式外,還需要32位元的暫存器,並且無法在286上面執行(即使286支援保護模式)。

即使在32位元晶片上已經打開了保護模式,但是為了仿照IBM XT系統記憶體連續的設計特性,1 MiB以上的記憶體並無法存取。這種限制可以由打開A20匯流排來迴避。

在保護模式下,前面32個中斷都是保留給CPU例外處理用。例如,中斷0D(十進制13)是一般保護模式錯誤,而中斷00是除以零

286的保護模式定址

編輯
 
286CPU在保護模式下的定址

286出現之前,x86的地址匯流排為20位,使用16位元的段基址(段首地址的高16位元)與4位元的段內偏移量,段基址左移4位元後與段內偏移量相加形成20位的實體位址,來對220(即1MiB)的地址空間定址。1982年問世的286 CPU首次使用了保護模式定址。286 CPU的地址匯流排為24位元,定址空間為224(即16 MiB)。而286 CPU的暫存器仍為16位元。[1]定址時,段暫存器儲存的數據不再是主記憶體實體位址,而是稱作選擇器(selector),其中高13位指向描述符表(descriptor table)的條目;最低的兩位數據定義了請求的權限,從0到3,0是最高權限,3是最低權限;剩下的一位表示是使用全域描述符表(GDT)還是局部描述符表英語Local Descriptor Table(LDT)。描述符表的條目為8位元組長,包括24位元長的段起始實體位址、16位元長的段長(因此段的長度範圍從1 B到216 B,即不超過64 KiB)。每次主記憶體操作所要訪問的實體位址為描述符表相應條目給出的24位元段起始實體位址再加上16位元的偏移量。可見,286保護模式下的應用程式能訪問的主記憶體線性地址空間僅為64 KB,非常有限。所以程式設計師編寫使用大主記憶體的應用程式時還必須使用遠指標、近指標,相當繁瑣。這影響了286保護模式的推廣使用。

從386開始的IA32保護模式定址

編輯
 
IA32 CPU保護模式下的4KiB分頁定址
 
IA32 CPU保護模式下的4 MiB分頁定址
 
應用程式的虛擬線性地址空間對映到分頁管理的實體位址空間

1985年問世的80386開啟了32位元CPU時代。[2]地址匯流排為32位元,定址空間為232(即4 GiB)。[3]386 CPU保護模式下有兩種主記憶體定址方式:

  • 可以分頁定址,這是此後的x86上的Windows作業系統與Linux作業系統最廣泛採用的方法;
  • 也可以非分頁定址而採取與286保護模式相容的定址方式,採用16位元的選擇器(selector)暫存器與32位元的偏移量暫存器定址,這時描述符表的條目中儲存的段起始實體位址為32位元,而段長的數據寬度為20位,但可以設置段長的粒度為1 B或4 KiB,所以段的最大長度可以是1 MiB或者4 GiB。

386 CPU開創的分頁主記憶體管理,比286保護模式定址具有更多的優點:

  • 作業系統可以控制與限制行程對頁面的訪問權限
  • 為應用程式創造一個連續的、獨立的、線性的虛擬記憶體空間
  • 頁面可以移出主記憶體,存入更慢速的次級外存硬碟。這使得作業系統可以使用比實體記憶體更大的儲存空間。

IA32的CPU通過兩級:頁目(page directory)與頁表(page table)實現4 KiB的分頁管理,這是最常見的IA32分頁定址方式。CR3暫存器儲存了行程的頁目的實體位址。頁目與頁表中每4位元組為一個單元,是一個32位元的值,當頁目項第0位為1時,表明頁表已經在實體記憶體中;當頁表項第0位為1時,表明訪問的數據已經在主記憶體中。另外,當頁目項第7位為1時,表明這是一個4M的頁面,這值已經是物理頁地址,用虛擬地址的低22位作為偏移量。

從應用程式角度,不再使用段地址暫存器(或稱選擇器),僅使用32位元的偏移量,為232(即4 GiB)的連續線性定址空間。

進入保護模式

編輯

進入保護模式前,必須初始化全域描述符表,並最少包含三個描述符:空描述符、代碼段描述符以及數據段描述符。並把(全域描述符表的所佔用的位元組數-1)和全域描述符表的實體記憶體地址儲存到GDTR暫存器中。如果是IBM相容的機器,則還需要打開A20匯流排

通過設置CR0暫存器的PE位進入保護模式。在設置完CR0暫存器的PE位後,需要進行遠轉移以清空PIQ。

; 设置CR0寄存器的PE位
mov eax, cr0       ; 必须通过其他寄存器来修改CR0寄存器
or eax, 1
mov cr0, eax

; 远转移 (cs = 代码段描述符)
jmp cs:@pmode

[bits 32]
@pmode:
; 现在已经进入了保护模式

參見

編輯

參考資料

編輯
  1. ^ A+ - Hardware. PC Microprocessor Developments and Features Tutorials. BrainBell.com. [2007-07-24]. (原始內容 (Tutorial/Guide)存檔於2022-03-31). 
  2. ^ Intel Global Citizenship Report 2003. [2007-07-14]. (原始內容 (Timeline)存檔於2008-03-22). 1985 Intel launches Intel386 processor 
  3. ^ 80386 Programmer's Reference Manual (PDF). Santa Clara, CA: Intel. 1986. Section 2.1 Memory Organization and Segmentation [2022-05-09]. (原始內容 (PDF)存檔於2018-12-28). 

外部連結

編輯