3 2 3節 特權級

2021-07-22 06:59:16 字數 2608 閱讀 1941

原來看第3.2.3節的時候,感覺很難的。為什麼會感覺難呢? 因為這一節談到的特權級別關係比較複雜,不容易弄清楚。這次重看一次這一節後,進行了一點小結,這才感覺比較清楚了。

這一節的主要內容可以用下面這個**來描述。

目標**段

jmp指令

call指令

直接呼叫

通過呼叫門

一致碼段

cpl>=dpl,不檢查rpl

可以跳轉到相同或者更高特權級別執行

cpl<=dpl_g,rpl<=dpl_g

cpl>=dpl

訪問呼叫門的規則同訪問資料段,即呼叫門只能被特權級別不低於其dpl(dpl_g)的**訪問。可以跳轉到相同或者更高特權級別執行。

非一致碼段

rpl<=cpl=dpl

只能跳轉到同特權級別的**段

1. 三種特權級別

cpl:當前特權級別。當前正在執行的**所處的特權級別,儲存在cs和ss的低2位中。

dpl:描述符特權級別,即段描述符中dpl欄位的值,是與描述符相關的特權級別。

rpl:請求特權級別,即用於訪問**、資料或者堆疊的段選擇子低2位的值。

注意特權級別的表示:有0至3這4個特權級別,0級最高,3級最低,即數字大則特權級別低。表中cpl、rpl、dpl等都是代表數字的。

2. 一致碼段和非一致碼段

(1)一致碼段:無論採用哪種方式跳轉到一致碼段,cpl都不改變(不變化為目標**段的dpl),也即在載入目標**段選擇子時,只載入高14位,表示cpl的低2位保持不變。

(2)非一致碼段:無論採用哪種方式跳轉到非一致碼段,cpl都發生改變,也即在載入目標**段選擇子時,將整個選擇子放入到cs中。

「一致」的意思就是:**段被呼叫執行時不使用自己的描述符的dpl,而採用呼叫者特權級別,cs的低2位保持不變,與呼叫者特權級別保持一致。

是不是一致碼段由描述符中的相應位標誌確定(參看47到49頁的**)。

3. jmp與call

jmp指令僅僅進行執行流程的跳轉,不會儲存返回位址。

call指令在進行流程跳轉前會儲存返回位址,以便在跳轉目標**中可以使用ret指令返回到call指令的下一條指令處繼續執行。執行段內跳轉時,只儲存eip;如果是段間跳轉,還儲存cs。

對於使用call指令(無論是直接呼叫還是通過呼叫門)進行的跳轉,如果跳轉後特權級別將發生改變(總是從低到高,從上述第2點知道,只有跳轉到非一致碼段時才會發生特權級別變化),則執行call指令前必須準備好任務狀態段tss。跳轉過程是:(1)儲存呼叫者的ss和esp到被呼叫者堆疊中(2)呼叫引數先儲存在呼叫者堆疊中,然後被複製到被呼叫者堆疊中(3)當前cs和eip被儲存到被呼叫者堆疊中。在通過call進行的有特權級別變化的跳轉中,堆疊會發生切換,這時要儲存當前堆疊指標(ss:esp),而當前指令指標(cs:eip)儲存到新的堆疊(被呼叫者堆疊)中,這是與沒有特權級別變化的跳轉不同的。沒有特權級別變化時,不需要儲存ss:esp,不存在呼叫引數的複製,不存在堆疊切換。

4. ret和retf

這兩個指令的功能都是呼叫返回。

(1) ret在返回時只從堆疊中取得eip;retf中的字母f表示far,即段間轉移返回,要從堆疊中取得eip和cs。

(2)兩個指令都可以帶引數,表示發生過程呼叫時引數的個數,返回時需要從堆疊中退出相應個數的引數

(3)恢復cs時,如果發現將發生特權級別變化(當前cs的低2位不等於從堆疊中取得的新的cs值的低2位。從上述第2點知道,只有跳轉到非一致碼段時才會發生特權級別變化,那麼,也只有從非一致碼段返回時才會發生特權級別返回),則還要從呼叫者堆疊中取得esp和ss恢復到相應暫存器中,也即恢復呼叫者堆疊。

5. 任務狀態段tss

為避免相互干擾,要求不同特權級別的**執行時使用不同的堆疊,也就是在特權級別發生改變時必須切換堆疊段。0、1、2特權級別的堆疊指標儲存在tss中,在跳轉到相應級別時從tss中取出相應的堆疊指標進行堆疊切換。因為只有從低特權級別跳轉到高特權級別時才需要從tss中取得新的堆疊指標,所以tss中不存在最低特權級別3的堆疊指標。

綜上所述,所有的複雜只有一點:僅僅在通過呼叫門從低特權級別跳轉到高特權級別的非一致碼段時,才會發生cpl改變,才需要先準備好tss,才會發生堆疊切換(在呼叫前從tss中取得新的堆疊指標;呼叫返回時從被呼叫者堆疊中取得原堆疊指標進行恢復)。

cpl、rpl、dpl的區別

cpl(current   privilege   level) 當前(**)特權級。在保護模式下,cs暫存器、ss暫存器中分別存放著**段、堆疊段的選擇子。cpl在cs、ss的第0、1位(第0位到15位)中。cpl一般情下等於所裝載的段的特權級。對於一致**段來說,cpl不會隨著所裝載的段的特權級而改變。

dpl(descriptor   privilege   level)描述符特權級,在每個儲存段(資料段、**段、堆疊段)描述符、門(呼叫門、任務門、中斷門、陷阱門)描述符、任務狀態段(tss)描述符的第5個位元組(第0位元組到第7位元組)的第5、6位(第0位到第7位)中。dpl主要用來與cpl比較,來確定當前**是否能夠訪問相應的段。

rpl(request   privilege   level) 選擇子特權級,在每個選擇子的第0、1位(第0位到15位)中。rpl主要用來改寫cpl,當進行段訪問的時候,取cpl和rpl中數值大的乙個(即取許可權小的乙個)。如:cpl為0,要訪問的呼叫門dpl為2,但是選擇子的rpl為3,此時不可以訪問呼叫門。

CPL,DPL,RPL 特權級檢查

1 cpl,dpl,rpl都位於 rpl request privilege level,請求特權級,位於段暫存器後兩位 dpl descriptor privilege level,描述特權級,位於gdt idt中 cpl current privilege level,當前特權級,cs.rpl ...

特權級之間的轉換

特權級之間的轉換包括 段之間的轉換和資料段之間的轉換。對於資料段之間的轉換,只檢查選擇子中rpl和段中dpl的值,如果rpl dpl則可以轉換,而對於 段之間的轉換,情況會稍微複雜。段之間特權級的轉換主要通過jmp和call指令實現,jmp和call的運算元可以直接是選擇子,但注意在用call時,要...

保護模式特權級概述

在ia32的作業系統中,段被分為了4個特權級,分別為0 3級,有時候我們也叫做ring0 ring3,其中,數值越小特權級越高。如下圖所示 圖中,核心 和資料所在的段的特權級都比較高,一般在ring0,而使用者程式所在的段的特權級較低,一般在ring3。當低特權級的任務試圖在未被允許的情況下訪問高特...