http://www.haogongju.net/art/898434

《Orange’s 一個操作系統的實現》3.保護模式7-特權級轉移(通過調用門轉移目標段-有特權級轉換-理論)

作者:Aoysme | 出處:博客園 | 2011/11/20 19:59:21 | 閱讀19

A.關於堆棧

   jmp指令:不影響堆棧

   call指令:影響堆棧,對於短調用來說,call指令執行時會將下一條指令的eip壓棧,到ret指令時,這個eip會被從堆棧中彈出。

                          對於長轉移;還會將cs壓棧

B.call指令堆棧示意圖

   假設函數foo(param1,param2,param3)

   1.短調用時堆棧示意圖

51B54}P2X59GTW5{BSL03G5[4]

   2.短調用返回時堆棧示意圖

[68GQMTTDB5Z6ZG6T59@]6Q

   3.長調用時堆棧示意圖

OEPQLY~}AHH]}BMU5257O7U

   4.長調用返回時堆棧示意圖(通過帶參數的ret指令)

JBS)`9(4T~9H%0[4N3O[@YF

   5.有特權級變換的轉移及返回時的堆棧變化

       轉移時示意圖

[5)V4XR4))A3O`5C9~$3RNT

    返回時示意圖

K]HT6P(V_B5DZVK{W1B~91S

由於堆棧可能會發生變化,所以intel提供了將堆棧A的諸多內容複製到堆棧b中。這裏我們只涉及到連個堆棧,而事實上,由於每個任務

最多在都可能在4個特權級之間轉移,所以每個任務實際上需要4個堆棧。原有的ss和一個esp就不能滿足我們的需要,這是就要使用到

TSS(Task-State Stack),一個數據結構,包含多個字段

6.32位TSS結構如下

   image 

   TSS字段偏移4到27的3個ss和3個esp,當發生堆棧切換時,內層的ss和esp就是從TSS裏面取得.

 

C.轉移過程概述

   call過程(低特權->高特權)

   1.根據目標代碼段的DPL(新的CPL)從TSS中選擇應該切換至哪個ss和esp

   2.從TSS中取得新的ss和esp.在這個過程中如果發現ss、esp或者TSS界限錯誤都會導致無效TSS異常(#TS)

   3.對ss描述符進行檢驗,如果發生錯誤同樣產生#TS異常
   4.暫時性地保存當前ss和esp的值

   5.加載新的ss和esp

   6.將剛剛保存的ss和esp的值壓入堆棧
   7.從調用者堆棧中將參數複製到被調用者堆棧(新堆棧)中,複製參數的數目有調用門中Param Count(最多31個參數,大於31可以使用結構指針)

      一項來決定。如果Param Count 爲0的話,將不復制參數

   8.將當前的cs和eip壓棧

   9.加載調用門中指定的新的cs和eip,開始執行被調用的過程

   ret過程(高特權->低特權)

   1.檢查保存的cs中的RPL以判斷返回時是否要交換特權等級

   2.加載被調用者堆棧上的cs和eip(此時會進行代碼段描述符和選擇子類型和特權級檢驗)

   3.如果ret指令含有參數,則增加esp的值以跳過參數,然後esp將指向被保存過的ss和esp.注意,ret的參數必須對應調用門中的param count

   4.加載ss和esp,切換到調用者堆棧,被調用者的ss和esp被丟棄。這裏會進行你個ss描述符、esp以及ss段描述的檢驗
   5.如果ret指令含有參數,增加esp的值以跳過參數(此時已經在調用者堆棧中)

   6.檢查ds、es、fs、gs的值,如果其中哪一個寄存器指向的段的DPL小於CPL(此規則不使用與一致代碼段),那麼一個空描述符會被加載到該寄存器


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章