7.7.1 控制轉(zhuǎn)移的分類
在一個任務(wù)中進行控制轉(zhuǎn)移有以下3種情況:
(1) 段內(nèi)轉(zhuǎn)移,段內(nèi)轉(zhuǎn)移不訪問描述符,不改變特權(quán)級,使用JMP/CALL/RET指令,實現(xiàn)段內(nèi)控制轉(zhuǎn)移。
(2)同一特權(quán)級內(nèi)的段間轉(zhuǎn)移,在同一特權(quán)級內(nèi)的段間轉(zhuǎn)移又可分成如下3種情況:
①訪問代碼段描述符的長轉(zhuǎn)移指令JMP/CALL/RET和NT位=0時的IRET指令;
②訪問調(diào)用門的長轉(zhuǎn)移JMP/CALL指令;
③訪問中斷/陷阱門的INTn指令,外部中斷和異常中斷。
(3)特權(quán)級間的段間轉(zhuǎn)移,特權(quán)級間的段間轉(zhuǎn)移也有以下3種情況:
①訪問調(diào)用門的長CALL指令;
②訪問中斷/陷阱的INT指令,外部中斷和異常中斷。


7.7.2任務(wù)內(nèi)的控制轉(zhuǎn)移
在一個任務(wù)內(nèi)控制轉(zhuǎn)移的示意圖如圖7.26所示。

1. 段內(nèi)轉(zhuǎn)移 從表7.6和7.7可以看到,最簡單的一種情況就是段內(nèi)轉(zhuǎn)移。因為在轉(zhuǎn)移前后,段、特權(quán)級等均不改變,故只要利用JMP或CALL指令即可實現(xiàn),例如: JMP NEARPTRTABLE[EBX] ;段內(nèi)轉(zhuǎn)移 JMP WORDPTR[BX] ;16位操作的段內(nèi)轉(zhuǎn)移 JMP DWORDPTR[EBX] ;32位操作的段內(nèi)轉(zhuǎn)移 如前所述,段內(nèi)轉(zhuǎn)移不改變CS,只改變了IP或EIP。 2. 段間直接控制轉(zhuǎn)移(同一個特權(quán)級內(nèi)) 由描述符所提供的段基地址及由指令給出的偏移地址共同決定轉(zhuǎn)移或調(diào)用子程序的入口地址,即入口地址=段基地址+偏移量 上述過程可由圖7.27來表示。

3. 利用調(diào)用門進行段間的間接控制轉(zhuǎn)移(不同特權(quán)級之間或同一特權(quán)級內(nèi))在用CALL指令訪問調(diào)用門時,當門內(nèi)目的選擇器所指定的代碼段的描述 符的DPL≤CPL關(guān)系成立時,才能轉(zhuǎn)移。 4. 調(diào)用門的堆棧處理 CALL指令的執(zhí)行過程如下: ①將調(diào)用程序低特權(quán)級堆棧段的選擇符進行0擴展,變?yōu)?2位并壓入轉(zhuǎn)移的目的堆棧。 ②將調(diào)用程序低特權(quán)級堆棧段的ESP壓入新棧,即轉(zhuǎn)移的目的堆棧。 ③將調(diào)用門中字數(shù)域所指定的參數(shù)從調(diào)用者堆棧拷貝到轉(zhuǎn)移的目的堆棧。 ④將調(diào)用處的斷點CS選擇符進行0擴展,變?yōu)?2位并壓入新堆棧。 ⑤將斷點的EIP壓入堆棧。


