八篇關於保護模式的文章,今天總算告一段落了。:D: 言歸正傳。
今天我們學習陷阱門,先來看看理論部分。
1。異常來源:
1)處理器檢測到程式錯誤產生異常。
在程式運行期間,檢測到程式錯誤。被進一步分為:faluts(故障),traps(陷阱),aborts.(中止)
2)軟體產生異常, int0 ,int 3, BOUND等指令在軟體中產生異常。
3)機器檢測異常,由處理器檢查內部晶片和外部匯流排產生的異常。
windows通過中斷門,任務門或者陷阱門進行中斷或者異常處理,前面我們學習過中斷門和任務門,今天我們一起看看陷阱門的結構。
13049
陷阱門適宜於處理異常,在有出錯碼的情況下,轉入處理常式之前還要把出錯碼壓入堆棧。只有異常處理才可能有出錯碼。
13050
a,b是沒有特權變化時的情況, c,d是有特權變化的情況。
2.異常處理的步驟
由硬體自動實現的異常處理的步驟如下:
1).判斷中斷向量號要索引的門描述符是否超出IDT的界限。若超出界限,就引起通用保護故障,出錯碼為中斷向量號乘8再加2。
2). 從IDT中取得對應的門描述符,分解出選擇子、位移量和描述符屬性類型,並進行有關檢查。描述符只能是任務門、286中斷門、286陷阱門、386 中斷門或386陷阱門,否則就引起通用保護故障,出錯碼是中斷向量號乘8再加2。
3).如果是由INT n指令或INTO指令引起轉移,還要檢查中斷門、陷阱門或任務門描述符中的DPL是否滿足CPL<=DPL(對於其它的異常或中斷,門中的DPL被忽略)。這種檢查可以避免應用程式執行INT n指令時,使用分配給各種裝置用的中斷向量號。如果檢查不通過,就引起通用保護故障,出錯碼是中斷向量號乘8再加2。
4).門描述符中的P位必須是1,表示門描 述符是一個有效項,否則就引起段不存在故障,出錯碼是中斷向量號乘8再加2。
5). 根據門描述符類型,分情況轉入中斷或例外處理常式。對於異常處理,在開始上述步驟之前,還要根據異常類型確定返回點;如果有出錯代碼,則形成符合出 錯碼格式的出錯碼,並在實際執行例外處理常式之前把出錯碼壓入堆棧。
3.通過陷阱門的轉移
如果中斷向量號所指示的門描述符是386陷阱門,那麼控制轉移到當前任務的一個處理常式過程,並且可以變換特權級。與其它調用門的 CALL指令一樣,從陷阱門中擷取指向處理常式的48位全指標。其中16位選擇子是對應處理常式或程式碼片段的選擇子,它指示通用描述元表GDT或局 部描述符表LDT中的程式碼片段描述符;32位位移指示處理常式進入點在程式碼片段內的位移量。通過陷阱門的轉移過程如下所示,該過程由硬體自動進行。
(1)若選擇子為空白,則產生通用保護故障;
(2)取對應的描述符;
(3)若非儲存段描述符,則產生通用保護故障;
(4)若非一致程式碼片段且DPL且段存在, 則切換到內層堆棧;
(5)調整RPL=0;
(6)把描述符裝入CS;
(7)若入口位移越界,則產生通用保護故障;
(8)EFLAGS壓入堆棧;
(9)CS 壓入堆棧;
(10)EIP壓入堆棧;
(11)使TF=0,NT=0;
(12)若有出錯碼,則把出錯碼壓入堆棧;
(13)轉入處理常式。
4.異常處理後的返回
指令IRET用於從例外處理常式的返回。該指令的執行根據任務嵌套標誌NT位是否為1分為兩種情形。
NT位為1,表示是嵌套任務的返回。當前TSS中的連結欄位儲存有前一任務的TSS的選擇子,取出該選擇子進行任務切換就完成了返回。這種情形在由通過任務門轉入的例外處理常式返回時出現,因為在由中斷門或陷阱門轉入處理常式時,NT位已被清0。
NT位為0,表示當前任務內的返回。這種情形在由通過中斷門或陷阱門轉入的中斷或例外處理常式返回時出現。具體進行的操作包括:從堆棧頂彈出返回指 針EIP及CS,然後彈出EFLAGS值。彈出的CS選擇子的RPL欄位,確定返回後的特權級。如果返回選擇子的RPL與CPL相同,則不進行特權級改 變。若RPL規定了一個外層特權級,則需要特權級改變,從內層堆棧中彈出外層堆棧的指標ESP及SS的值。這些做法與RET指令相似。例如,使用CS選擇
子的RPL,而不是由選擇子標識的段的DPL,是為了返回到不在DPL給定特權級的一致程式碼片段。若彈出的CS的選擇子的RPL規定了一個內層特權級,則產 生通用保護故障。需要注意的是,對於IRET指令,儲存在當前堆棧中的返回地址中的選擇子欄位必須指向程式碼片段描述符。而不能是系統段或門描述符。否則將引 起通用保護故障。
對於提供出錯代碼的例外處理常式,必須先人為地從堆棧中彈出出錯代碼,然後再執行IRET指令,及出錯代碼不會自動被處理器彈出或取消。
中斷返回指令IRET不僅能夠用於由中斷/異常引起的嵌套任務的返回,而且也適用於由段間調用指令CALL通過任務門引起的嵌套任務的返回,如前文所述,在執行通過任務門進行任務切換的段間調用指令CALL時,標誌寄存器中的NT位被置為1,表示任務嵌套。而RET指令不能實現此功能。