1.特權級
特權級(Privilege Level),是存在於描述符及其選擇子中的一個數值,Intel處理器可以識別4個特權級別:(大)0~3(小)。
- 對於代碼段,段描述符TYPE位中C=0則爲非依從代碼段,C=1爲依從代碼段, 依從代碼段允許從特權級比自己的低的段轉入;
種類 | 解釋 | |
---|---|---|
CPL (當前特權級) | 當前CS段段選擇子低2位。進入保護模式CPU自動設CPL=0,以便將控制轉移到操作系統代碼段; | |
特權指令:CPL=0時才能執行的指令,如lgdt,hlt,mov等; | ||
DPL (描述符特權級) | 段描述符DPL字段; | |
不同種類段DPL作用 | 數據段:訪問此段的最低級別; | |
非依從段(不調用門):訪問此段要相同的優先級; | ||
調用門:訪問調用門描述符的最低優先級,至於門指向的段能不能訪問另說; | ||
依從段和非依從(調用門):訪問此段最高優先級; | ||
TSS:訪問TSS最低優先級; | ||
RPL (請求特權級) | 即請求者的特權級,非CS段段選擇子低2位; | |
IO特權級 | 標誌寄存器EFLAGS中IOPL位; CPL<=IOPL所有IO端口都允許,CPL> IOPL總體上不允許,個別允許; |
CPL和RPL的對比和解釋:
CPL爲當前特權級,RPL爲請求特權級,都是段選擇子的低二位。一般請求者都是當前程序自己,因此CPL=RPL,但若運行程序不是請求者,則CPL!=RPL。
實例說明:
應用程序DPL=3,CPL=3,通過門調用了操作系統例程==> CPL=0,並且在調用OS例程時傳遞參數(應用程序自己的數據段的段選擇子,則這個段選擇子的RPL爲3),則相當於,OS例程在CPL=0的情況下,使用RPL=3的段選擇子==> CPL!=RPL;
並且若RPL=3的段選擇子指向的是操作系統的數據段,則雖然CPL=0,但由於RPL(3)>目標DPL(0)==> 訪問失敗,確保特權代碼不會代替應用程序訪問一個段。
注: 由於選擇子RPL是由應用程序自己提供的,操作系統系統應將應用程序提供的段選擇子RPL字段設爲請求者的特權級DPL,指令與具體用法如下:
//調整段選擇子RPL字段值
//目的操作數可以是包含了16位段選擇子的寄存器/16位單元內存地址;源操作數只能是寄存器
arpl r/m16(目),r16(源)
//該指令執行時,處理器檢查:若目的操作數RPL數值上<源操作數RPL==>
//設置ZF標誌,增加目的操作數RPL值,使之與原操作數RPL操作數值相同(否則==>什麼也不發生)
//OS具體方法:從棧中獲得調用者代碼段選擇子(CS內容)作爲源操作數,調用者傳來的選擇子作爲目的操作數
一般特權級檢查規則(數值比較):
- 將控制直接轉移到非依從代碼段檢查:
CPL=目標DPL,RPL=目標DPL ,CPL不發生變化 ; - 將控制直接轉移到依從代碼段檢查:
CPL>=目標DPL,RPL>=目標DPL ,CPL不發生變化; - 處理器將段選擇子傳遞到段寄存器(DS,ES,FS,GS)時檢查:
CPL<=目標DPL,RPL<=目標DPL - 修改SS時:CPL=目標DPL,RPL=目標DPL
- 高特權級程序可以訪問低特權級的數據段,反之不能。訪問之前要修改段寄存器==>(3)
- 處理器要求,任何時候,棧段特權級=CPL,因此隨着程序運行,要對SS進行修改==>(4)
上述規則,不滿足則會引起異常中斷。
2.調用門
實現控制在特權級之間的轉換,除了依從代碼段,還有就是使用門(Gate)。門即門描述符,與段描述符不同,段描述符用於描述內存段,而門描述符用於描述可執行代碼。門按用途能分爲調用門,中斷們,任務門。
調用門用於在不同特權級的程序之間進行控制轉移,它本身只是一個描述符,可以安裝在GDT或LDT中。
調用門描述符格式:
調用門特權級檢測規則(數值比較):
通過調用門實現控制轉移,可以使用jmp far
和call far
指令,描述符選擇子必須指向調用門,偏移量忽略;
指令 | 特權檢查規則(數值比較) | CPL變化 | |
---|---|---|---|
CALL FAR | CPL<=調用門描述符DPL,RPL<=調用門描述符DPL(即先不管調用門指向誰,只有特權級比門DPL高的才能調用該門) 依從或不依從代碼段:CPL>=目標代碼段描述符的DPL | 不一定 | |
CALL FAR | CPL<=調用門描述符DPL,RPL<=調用門描述符DPL 目標代碼段爲依從:CPL>=目標代碼段描述符的DPL 目標代碼段爲非依從:CPL=目標代碼段描述符的DPL | 不改變 |
處理器在執行指令call 0x0040:0x0000c000
時,先用該選擇子訪問GDT/LDT,若指向門描述符,則只要選擇子部分,偏移量丟棄;若指向普通代碼段描述符,則按一般處理。