1. 程式人生 > >中斷和異常

中斷和異常

行程 操作數 多說 技術分享 png 正在 內部 int 通知


中斷和異常的目的:

為了讓CPU能夠暫停當前的任務,轉去處理突發事件或者其他需要處理的任務,於是設計了中斷interrupt跟異常exception機制。
1. 中斷

中斷通常是CPU外部的輸入輸出設備(硬件)觸發的,供外部設備通知CPU有事情需要處理,因此又叫做中斷請求,
中斷請求的目的是希望CPU暫時停止當前正在執行的程序,轉去讓CPU去處理中斷請求對應的中斷處理例程(ISR-interrupt service routine).

我們知道有些任務是不可打斷的,為了防止CPU被打擾,可以通過執行CLI(clear interrupt)指令來清除標誌寄存器(EFLAGS)的IF位,使CPU暫時不受打擾。但是這樣只能讓CPU不受可屏蔽的中斷(maskable interrupt)的打擾, 一旦有不可屏蔽中斷non-maskable interrupt->NMI發生,CPU任然要去處理,但是我們知道NMI很少,而且不可打斷的代碼很少,所有一般不用考慮太多。
可屏蔽中斷是由CPU的INTR引腳觸發
不可屏蔽中斷是CPU的NMI引腳觸發(此處最好看微機原理這本書比較好,IRQ那裏也不錯)

值得一提的是中斷機制讓外設和CPU有了很好的通信功能,成了外設你有事你打斷我的機制,所以有中斷機制的硬件是很厲害的
他可以隨意打斷CPU


在硬件級別,中斷由一塊專門的芯片來管理,稱為中斷控制器,它負責分配中斷資源和管理各個中斷發出的中斷請求。也就是IRQ
但我們的IRQ是怎麽實現的呢,他和中斷號建立了鏈接,最終也走的是IDT服務例程
IR0 時鐘
IR1 鍵盤
IR3 IR4 串口1 串口2 串口通信還是微機原理與接口技術那本書(8251等的實現)
IR6 軟盤驅動(很少了)
一個IRQ可以由多喝設備對象共享,不多說了,這是PCI總線允許多個PCI設備共享一個中斷請求信號,在windows驅動開發那本書上
在設備對象那部分有類似的總線共享


異常:與中斷不同,異常通常是CPU在執行指令時候因為檢測到預先定義的某個或者多個條件而產生的同步事件。
異常的來源有三種:

一: 程序錯誤,當CPU執行程序指令遇到操作數有錯誤或者檢測到指令規範中定義的非法情況,前者比如除數是0,這是錯誤異常,
後者比如用戶層執行特權指令什麽的。比如函數不能直接用RING0

二:來自某些特殊指令,這些指令就是為了產生異常,比如INT3指令,(具體INT3的實現可以看我上篇堆軟件斷點的解釋)是斷點異常
是為了切到調試器上

三:來自CPU引入的機器檢查異常,即當CPU指令執行期間檢測到CPU內部或者外部的硬件錯誤。

比較:

根本差異是異常來自於CPU本身,是CPU主動產生的,而中斷來自於外部設備,是中斷源發起的,CPU是被動的。所以確切的說,INT n指令是異常,而非中斷,它只是設置了標誌位,是由CPU本身產生的。

盡管中斷和異常有著本質區別,但是CPU跟操作系統還是用統一的方式來響應跟管理他們的。


異常的三種情況:
錯誤Fault:導致錯誤的異常通常可以被糾正,一旦糾正後程序可以無損失的恢復執行。因為發生異常時候的狀態都保存了下來。某些情況下也是不可恢復的。

陷阱Trap:與錯誤異常不同,當CPU報告陷阱類異常時,導致該異常的指令已經執行完畢,壓入棧的CS和EIP(也就是異常處理的返回地址)是導致該異常的指令執行後緊接著執行的下一條指令,所以執行的是下一條要執行的指令,下一條不一定是相鄰指令,比如跳轉指令。導致陷阱類的異常通常也是可以無損失的恢復執行的,比如INT 3導致的斷點異常,可以從調試器返回到程序繼續執行。

中止abort:中止類異常主要用於報告嚴重的錯誤,不允許恢復繼續執行。因為一是CPU並不總能保證這種情況下報告的異常的指令地址是精確的,二是出於安全性考慮,這類異常可能是由於導致該異常的程序執行非法操作導致的。


錯誤類型之頁錯誤(缺頁,算法有FIFO,LRU算法等)

技術分享圖片

中斷和異常