保護模式下的跳轉

主要是兩類:

不改變特權、改變特權

1. 不改變特權級可以用段間、段內的call或者jmp。段間不做判斷。段間會看目的段是什麼代碼段。

如果是非一致代碼段,則必須CPL=DPL,並且RPL<=DPL。跳轉後CPL不變。
如果是一致代碼段,對RPL不做判斷,則必須CPL>=DPL,即外環可以跳入內環,但CPL不變。

2. 改變特權級,必須通過門(調用門、任務門、中斷門、陷阱門)。通過門由外環跳入內環,通過ret、lret、inet跳回外環。


段間轉移:用48位地址(選擇子+偏移量)描述要跳轉的地址。
直接段間轉移:直接用48位地址
間接段間轉移:用指向48位地址的調用門、人物們、TSS描述符。這時只有描述子有用,偏移量無作用。具體地址是看門對應的地址。

JMP不管是直接還是間接,都只能是同特權級之間跳轉。


當段間轉移指令JMP和段間調用指令CALL所含指針的選擇子指示調用門描述符時,就可以實現通過調用門的轉移。但只有CALL指令能變換到內層的特權級,JMP指令只能轉移到同級的代碼。

調用門描述符轉移的入口點包含目標地址的段及偏移量的48位全指針。在執行通過任務門的段間轉移指令JMP或段間調用指令CALL時,指令所含指針內的選擇子用於確定調用門,而偏移被丟棄;把調用門內的48位全指針作爲目標地址指針進行轉移。

處理器採用與訪問數據段相同的特權級規則控制對門描述符的訪問。調用門描述符的DPL規定了訪問該門的最外層特權級,在取出調用門內的48位全指針,把它作爲目標地址指針向目標代碼段轉移之前,要進行特權級檢查。只有在相同級或者更內層特權級的程序纔可訪問調用門,即CPL<=調用門的DPL。同時,還要求指示門的選擇子的RPL必須滿足RPL<=調用門的DPL的條件。檢測通過後,纔開始向目標代碼段轉移的步驟。其中還要檢測目標描述符是否爲代碼段描述符,調用門內的選擇子指示的描述符必須是代碼段描述符。此外,在裝載代碼段描述符高速緩衝寄存器之前調整代碼段選擇子的RPL=0,也即調用門中代碼段選擇子的RPL被忽略。

在裝載CS高速緩衝寄存器時,還要對目標代碼段描述符進行保護檢測。檢測過程中的DPL不再是調用門的DPL,而是調用門內選擇子所指示的目標代碼段描述符的DPL。段間調用指令CALL和段間轉移指令JMP所做的檢測不一樣。

對於使用調用門的段間轉移指令JMP,檢測條件與段間直接轉移相同。由於已置RPL=0,所以可認爲 RPL<=DPL的條件總能滿足。所以,對於普通的非一致代碼段,當CPL=DPL時,發生無特權級變換的轉移;對於一致代碼段,在滿足CPL>=DPL時也發生無特權級變換的轉移;其它情形就引起異常。

對於使用調用門的段間調用指令CALL,情形就不同了。由於已置RPL=0,所以可認爲RPL<=DPL的條件總能滿足。對於一致代碼段,在滿足CPL>=DPL時發生無特權級變換的轉移。對於非一致代碼段,當CPL=DPL時,仍發生無特權級變換的轉移;當CPL>DPL時,就發生向內層特權級變換的轉移,將調用門中的選擇子和偏移裝入CS和指令指針EIP中,並使CPL保持等於DPL,同時切換到內層堆棧。

綜上所述,使用段間調用指令CALL,通過調用門可以實現從外層程序調用進入內層程序(JMP指令只能實現無特權級變換的轉移);通過調用門也可實現無特權級變換的轉移。需要注意的是,JMP指令和CALL指令都不能實現向外層特權級的轉移否則會引起異常。

當然,CALL指令在最後把目標代碼段的指針裝入CS和EIP之前,要把原CS和EIP,即返回地址保存到堆棧。如無特權級變換,堆棧保持不變,返回地址就保存在原堆棧中;否則,返回地址保存在內層堆棧中。

轉載於:https://www.cnblogs.com/fanzi2009/archive/2009/05/29/1491886.html

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