## 9.6 中斷任務和中斷子程序(Interrupt Tasks and Interrupt Procedures)
和CALL指令能調用一個子程序或任務一樣,中斷、異常也可以“調用”一個子程序或任務來做中斷處理程序。當識別了一個中斷、異常時,處理器使用中斷號來索引IDT。如果處理器索引到的是一個中斷門或陷阱門,它就象CALL指令調用一個調用門一樣調用一個中斷處理子程。如果處理器索引到一個任務門,它就象CALL指令調用了一個任務一樣,做任務切換。
### 9.6.1 中斷子程序(Interrupt Procedures)
如圖9-4所示,中斷門、陷阱門間接地指向了一個在當前任務上下文里的子程序。門里的選擇子指向了一個在GDT或LDT中的可執行代碼段描述符。偏移部分字段則指向了中斷、異常處理子程序的入口。
80386象使用CALL指令一樣喚醒一個中斷、異常處理子程序。不同之處在下面介紹。

9.6.1.1 中斷子程堆棧(Stack of Interrupt Procedure)
和CALL指令的控制轉移一樣,當控制轉移到中斷、異常處理子程序時,程序使用堆棧來存儲返回被中斷程序的一些信息。如圖9-5所示,中斷時,先把EFLAGS寄存器推入堆棧,然后再是返回地址。
某些類型的異常還可以引起一個出錯碼,出錯碼被壓入堆棧。異常處理程序可以使用出錯碼來幫助排錯。
9.6.1.2 從中斷子程序返回(Returning from an Interrrupt Procedure)
中斷處理程序的返回方式也不和一般的子程序相同。IRET指令用來從中斷子程序中返回。IRET和RET指令相似,只是要增加EIP額外的4個字節(因為在堆棧上的標志)和把保存的標志。只有當CPL為0的時候,標志寄存器的IOPL字段才可以改變。IF標志位只有當CPL<=IOPL時,才會改變。

9.6.1.3 被中斷子程使用的標志位(Flags Usage by Interrupt Procedure)
不管是中斷門還是陷阱門,中斷發生,且當前的TF被保存在堆棧上時都會清除TF(陷阱標志)標志位。這樣,處理器就可以在中斷處理程序中禁止用于調試的單步中斷異常。下一個IRET指令將從堆棧上的EFLAGS寄存器映象恢復TF位。
中斷門和陷阱門的主要區別是對于IF(允許中斷標志)標志位的影響。通過中斷門進入中斷處理程序后會清除IF位,從而禁止了其它中斷的發生。其后的IRET指令會恢復IF位到堆棧上的EFLAGS映象。通過陷阱門進入的中斷不改變IF位。
9.6.1.4 在中斷子程序內的保護(Protection in Interrupt Procedures)
對于中斷子程序的特權級規則和普通的子過程調用類似:CPU不允許中斷控制從當前特權級到低特權級。一個試圖破壞這個規則的操作將引起通用保護異常。
因為中斷的發生一般是可預測的,這種特權級的約束著中斷、異常處理程序的執行。以下的方法都可以用來防止這個規則的破壞。
+ 把處理程序放到一個一致性段中。這種策略可以處理一些異常(比如,除法錯)。這樣的處理程序只能使用堆棧上的數據。如果它需要在數據段時的數據,數據段應該為特權級3,讓它不被任何保護。
+ 把處理程序放在特權級0的段。
### 9.6.2 中斷任務(Interrupt Tasks)
在IDT中的任務門間接的指向了一個任務,如圖9-6所示。門里的選擇子字段指向了一個GDT中的TSS描述符。
當一個IDT中的中斷、異常向量指向一個任務時,任務切換發生。將中斷用任務來處理有以下兩個好處:
+ 上下文被完整的自動保存。
+ 中斷處理程序可以通過一個完全隔開的地址空間,和其它任務完全隔開,通過了LDT和頁目錄。
處理器的任務切換操作在第7章中已講述。中斷任務通過執行一條IRET指令返回到被中斷的任務。
如果任務切換是被一個帶出錯碼的異常引起的話,處理器將自動壓入出錯碼到中斷任務的第一條指令特權級的對應的堆棧中。
當在80386中的操作系統中使用中斷任務時,實現上就有兩個調度器:一個軟件調度器(操作系統的一部分)和一個硬件調度器(處理器中斷機制的一部分)。軟件調度器設計時應該考慮到,只要中斷允許時,硬件調度器可能在任意時間指派中斷任務。

- 第一章 80386介紹
- 1.1 該手冊的組織結構
- 1.2 其他文獻
- 第二章 編程基本模型
- 2.1 存儲器組織和段
- 2.2 數據類型
- 2.3 寄存器
- 2.4 指令格式
- 2.5 操作數選擇
- 2.6 中斷和異常
- 第4章 系統寄存器
- 4.1 系統寄存器 (System Registers)
- 4.2 系統指令 (System Instructions)
- 第五章 內存管理
- 5.1 分段地址轉換(Segment Translation)
- 5.2 分頁地址轉換(Page Translation)
- 5.3 混合分段和分頁地址轉換(Combining Segment and Page Translation)
- 第六章 內存管理
- 6.1 為什么要保護(Why Protection?)
- 6.2 80386保護機制概述(Overview of 80386 Protection Mechnaisms)
- 6.3 段級保護(Segment-Level Protection)
- 6.4 頁級保護(Page-Level Protection)
- 6.5 混合分頁和分段保護(Combining Page and Segment Protection)
- 第7章 多任務(Multitasking)
- 8.1 I/O 尋址(I/O Addressing)
- 7.1 任務狀態段(Task State Segment)
- 7.3 任務寄存器(Task Register)
- 7.4 任務門描述符(Task Gate Descriptor)
- 7.5 任務切換(Task Switching)
- 7.6 任務鏈(Task Linking)
- 7.7 任務尋址空間(Task Address Space)
- 第8章 輸入 輸出
- 8.2 I/O 指令(I/O Instructions)
- 8.3 保護和I/O(Protection and I/O)
- 第9章 異常和中斷(Exceptions and Interrupts)
- 9.1 識別中斷(Identifying Interrupts)
- 9.2 允許和禁止中斷(Enabling and Disabling Interrupts)
- 9.3 同時發生的中斷和異常的優先級(Priority Among Simultaneous Interrupts and Exceptions)
- 9.4 中斷描述符表(Interrupt Descriptor Table)
- 9.5 IDT 描述符(IDT Descriptors)
- 9.6 中斷任務和中斷子程序(Interrupt Tasks and Interrupt Procedures)
- 9.7 出錯碼(Error Code)
- 9.8 異常條件(Exception Conditions)
- 9.9 異常總結(Exception Summary)
- 9.10 出錯碼總結(Error Code Summary)
- 第10章 初始化(Initialization)
- 10.1 復位后處理器狀態(Processor State After Reset)
- 10.2 實模式初始化(Software Initialization for Real-Address Mode)
- 10.3 切換到保護模式(Switching to Protected Mode)
- 10.4 保護模式初始化(Software Initialization for Protected Mode)
- 10.5 初始化示例
- 10.6 TLB測試
- 第十四章 80386實地址模式
- 14.1 物理地址構成
- 14.2 寄存器和指令
- 14.3 中斷和異常處理
- 14.4 進入和離開實地址模式
- 14.6 實地址模式異常
- 14.7 與8086的不同
- 14.8 與80286實地址模式的不同