1.中斷和異常
- 外部(硬件)中斷:從處理器外部來的中斷信號,通過兩個信號線INTR(可屏蔽中斷)、NMI(非屏蔽中斷)引入處理器;
中斷控制器8259芯片(PIC):
每片8259只有8箇中斷輸入引腳,在個人電腦上使用,需要兩塊(主片、從片);
INTEL處理器允許256(0~255)箇中斷,8259負責提供其中15個,但中斷號不固定;
8259內部有8位中斷屏蔽寄存器(IMR),對應8箇中斷輸入引腳;
8259有自己的端口號主片(0x20、0x21),從片(0xa0、0xa1),可以用in、out指令改變狀態、中斷號及IMR;
計算機啓動後,8259主片中斷向量0x08~0x0F
,從片中斷向量0x70~0x77
,16位機下正常,但在32位機0x08~0x0F
已被用作異常向量==>若開啓保護模式需重新初始化8259主片中斷向量; - 內部中斷(異常、異常中斷):由執行指令引起的中斷,不受IF位影響,不需中斷識別總線週期,中斷類型固定,可以立即轉入相應的處理程序;
如除法溢出則產生中斷0,非法指令則產生中斷6; - 軟中斷:由指令
int
引起的中斷處理,不需中斷識別總線週期,中斷號在指令中給出;
BIOS中斷(BIOS功能調用):即在計算機加電之後,BIO程序執行期間建立起中斷處理程序,並填了中斷向量表,以方便使用最基本的硬件訪問功能,如指令int 0x16
調用鍵盤服務;
2.中斷描述符表
- 實模式下,內存低1MB爲中斷向量表(IVT);
- 保護模式下,需自己定義中斷描述符表(IDT),表內存放門描述符,包括中斷門、陷阱門、任務門;通過中斷描述符表寄存器(IDTR)定位IDT位置,IDT與GDT一樣,整個系統只有一個,所以不需要選擇器;
中斷門與陷阱門描述符結構如下,D爲0則表示16位模式下門,1則爲32位的門:
IDTR結構如下:
IDTR16位界限==>表大小2^16B=64KB,但處理器只能識別256種中斷,故通常只是用2KB,其他空閒槽位應將描述符P位清零,且與GDT不同,IDT第一個即偏移量爲0的描述符是有效的;
3.錯誤代碼
有些異常產生時,處理器會在中斷處理程序的棧中壓入錯誤代碼,通常表示異常和特定的段選擇子或中斷向量有關,且用指令iret/iretd
從中斷處理程序中返回時,處理器不會自動彈出,即需要手動彈出;
對外部異常(引腳引發),軟中斷異常(int n),處理器不會壓入錯誤代碼,就算本身有個錯誤代碼;
4.中斷過程
此處忽略門描述符是任務門情況,因爲若爲任務門則會引發任務切換;(任務門中斷過程)
- 中斷和異常發生
- 中斷向量號*8(偏移)+IDTR訪問IDT,取出中斷門/陷阱門描述符;
- 門描述符中取出目標代碼段選擇子(1)、32位段內偏移量(2)
- 查看門描述符TI位+(1),處理器訪問GDT/LDT取出目標段描述符;
- 段描述符中取出目標段基地址+(2)==>中斷處理程序32位線性地址;
- 若沒開啓分頁則該線性地址即物理地址,否則通過也部件轉化爲物理地址;
5.中斷和異常處理程序的保護
特權級保護(數值需滿足):
- 代碼段DPL:
CPL>=目標代碼段描述符DPL
,(中斷門與陷阱門檢查,任務門不檢查); - RPL:中斷異常沒有RPL字段,故不檢查RPL;
- 門DPL:通常不檢查中斷門/陷阱門描述符DPL;
但軟中斷int n
、單步中斷int3
、into引發中斷異常需檢查,防止低特權軟件通過軟中斷等訪問內核例程:CPL<=門描述符DPL
,(中斷門、陷阱門、任務門都檢查);
換棧:
當發生中斷時,可能正在運行較低特權級程序,則切換到高特權級的中斷處理程序需換棧;
- 根據中斷處理程序特權級,從當前TSS中取出棧選擇子、棧指針;
- 將就棧選擇子SS、棧指針ESP壓入新棧;
- 將EFLAGS、CS、EIP壓入新棧;
- 對於有錯誤代碼的異常,錯誤代碼壓入新棧;
- 若中斷處理程序與當前程序特權級相同,不用切換棧;
- EFLAGS、CS、EIP壓入當前棧;
- 對於有錯誤代碼的異常,錯誤代碼壓入當前棧;
EFLAGS_IF:
EFLAGS中IF位僅影響硬件中斷,對NMI、異常、軟中斷沒用;
EFLAGS中IF位爲’0’,則所有從INTR引腳來的中斷信號都被忽略,指令cli
清除IF位,指令sit
置IF位;
通過中斷門進入處理程序,EFLAGS中IF位自動清零,以禁止嵌套中斷;
通過陷阱門進入中斷程序,EFLAGS中IF位不變,以允許其他中斷優先處理;