一、基本概念和分類
????????計算機在執行程序的過程中,有時會遇到一些異常情況或者特殊請求;這時就需要計算機暫停正在運行的程序,轉而先去處理這些異常或特殊請求,處理結束之后再返回程序的斷點處繼續執行。這種處理方式就被稱為 “中斷”,計算機的這種功能就稱為 中斷處理;實現這種功能所需的軟硬件技術統稱為 中斷技術。
????????很顯然,對于一些突發情況和實時傳來的外部信號,相比時刻查詢的方式,使用中斷技術可以大大地提高計算機的整體效率。
????????能夠引發中斷的因素有很多,比如電源掉電、打印機請求、運算溢出、缺頁等等。通常將能夠引起中斷的各種因素稱為 中斷源。根據各種中斷源的類型,可以對中斷進行不同的分類。
1.中斷和異常
????????從中斷的來源看,直觀上可以分成兩類:一類是由外部設備向 CPU 發出的請求(比如打印),或者突發的外部事件或環境對計算機造成了影響(比如電源掉電),在 CPU 外部產生;另一類是 CPU 在執行指令時遇到的異常情況,在 CPU 內部產生。
????????通常將 CPU 內部產生的中斷稱為 異常(Exception),也稱作 內中斷。異常一般是 CPU 的控制單元(CU)在執行指令時遇到了意外情況、因而必須暫停處理;由于一定會在一條指令執行結束后才發出中斷,因此也被叫做 同步中斷。
????????與之對應,來自于 CPU 外部其它硬件設備的中斷,就被稱為 外中斷,或者直接叫做(狹義的) 中斷(Interrupt)。它們通常是外部設備依照 CPU 時鐘隨機產生的,因此也被叫做 異步中斷。
????????事實上,對于中斷(狹義)和異常,CPU 的處理流程都是先中止當前正在執行的程序、轉而去執行相應的中斷處理程序(稱為 “中斷服務程序”),完成中斷響應之后,再回到斷點處繼續執行。因此,一般可以把它們統稱為(廣義的)中斷。
2.中斷和異常的分類
????????中斷請求并不一定都非常急迫、必須立刻響應。CPU 可以對中斷進行判別、選擇,屏蔽某些中斷源的請求;根據是否可以被屏蔽,中斷(狹義)又可以分成兩類:
-
可屏蔽中斷:可屏蔽中斷有 “屏蔽” 和 “非屏蔽” 兩種狀態;處在屏蔽狀態的中斷,CPU 將不予以響應。I/O 設備的中斷請求都屬于可屏蔽中斷。
-
不可屏蔽中斷:一些急迫事件 CPU 必須予以響應,發出的中斷不能屏蔽。例如電源掉電就屬于不可屏蔽中斷。
?
????????而對于異常,由于它跟指令的執行有關,因此根據中斷處理完成后、接下來指令執行的情況,可以進一步進行分類: ?
-
故障(Fault):通常可以糾正,一旦糾正則程序可以重新執行原先產生中斷的那條指令;也稱為 “程序性事故”。例如運算溢出、缺頁異常。
-
陷阱(Trap):這種異常是人為設置的,表示自愿停止現行程序、轉入中斷處理,因此也叫 “自愿中斷”、“自陷”。一般計算機中都會設置陷阱指令,執行到它就會轉至別處做特殊處理,完成之后就返回到陷阱指令的下一條指令繼續執行。例如調試程序時的斷點設置、執行系統調用等。
-
異常中止(Abort):如果發生了嚴重的錯誤,程序無法繼續執行,那么就只能把控制權交給異常中止處理程序;而現行程序只能強制停止運行。例如硬件故障、系統表中無效的值等。
3.中斷系統
????????中斷改變了計算機執行程序的順序,因此需要 CPU 進行特別的處理。為了實現中斷處理的功能,CPU 中一般會設置專門的處理機構,這就是 中斷系統。
????????中斷系統主要需要解決以下一些問題:
-
中斷源怎樣向 CPU 發出中斷請求;
-
當有多個中斷源同時發出請求時,怎樣確定響應順序;
-
CPU 怎樣響應中斷請求;
-
CPU 響應中斷之后,怎樣保護現場;
-
CPU 響應中斷后,怎樣暫停原程序的執行、找到中斷服務程序的入口地址;
-
中斷處理結束后,CPU 如何恢復現場、返回原程序的斷點處;
-
如果中斷處理時又有新的中斷請求,應該怎樣處理。
接下來我們就通過學習中斷系統,來解決這些問題。
二、中斷的檢測
????????在 CPU 的指令周期中,最后一個階段就是 中斷周期。在一條指令執行階段的最后時刻,CPU 會發出 中斷查詢信號,檢測是否有中斷請求。如果有,則進入中斷周期進行中斷處理。
1.中斷請求標記
????????不同的中斷源都可以向 CPU 發出中斷請求,為了區分中斷源,中斷系統中會專門設置一個 中斷請求標記觸發器,簡稱 中斷請求觸發器,用 INTR 表示。當某個中斷源的觸發器 INTRi?為 “1” 時,就表示該中斷源發來了請求。
????????這些觸發器可以分散在各個中斷源的接口電路中,也可以集成在 CPU 中,組成一個 中斷請求標記寄存器。
????????寄存器里的每一位就對應著一個中斷源的請求觸發器。任意一個觸發器為 1,就表示對應的中斷源發出了中斷請求。 ?
2.中斷判優
????????在中斷系統中,同一時刻只能響應一個中斷源的請求。如果有多個中斷源同時發出了請求,那就需要中斷系統按照設定好的優先順序來依次響應;這被稱為 中斷判優。中斷源的優先級是依據重要性和急迫性而定的。
????????中斷判優就是要對一組中斷請求按優先級進行 “排隊”,可以用硬件和軟件兩種方式實現。
(1)硬件排隊
????????硬件排隊是直接用硬件電路實現中斷請求的排隊,具體方法很多,主要有兩種:一種是在 CPU 內統一設置一個 “排隊器”;另一種是在中斷源設備的接口電路中分別設置排隊器。
????????在 CPU 內設置排隊器:各中斷源的請求觸發器按優先級依次排列,高優先級的請求信號通過接入一個多輸入的與非門,來 “封住” 低優先級的中斷請求。
?
????????在接口電路中設置排隊器:每個接口電路中都設置一個反相器和一個與非門,與非門的輸出接入下一級,就可以實現對更低優先級中斷請求的封鎖。它們彼此之間直接連成鏈狀,因此也稱為 “鏈式排隊器”。 ?
(2)軟件排隊
????????軟件排隊,就是直接通過編寫查詢程序實現中斷請求的排隊。
????????程序按照中斷源的優先級,從高到低依次判斷是否有中斷請求,這樣就保證了中斷響應的順序。 ?
三、中斷的響應
1.中斷響應的條件
????????由于在處理中斷時,CPU 不應受到新中斷請求的打擾,因此需要有 “開關中斷” 的功能。在中斷系統中,這是由 允許中斷觸發器 EINT 和專門的指令來實現的。
????????EINT 可以被 開中斷指令 置 “1”,這時表示 CPU 打開了中斷功能,允許響應中斷源的請求;EINT 也可以被 關中斷指令 置 “0”,這意味著 CPU 關閉中斷功能,禁止響應中斷。
????????在 x86 架構的 CPU 中,EINT 就對應著 標志寄存器(程序狀態字)efl 中的一位,用 IF 表示。
????????因此可以總結,當 EINT = 1 且有中斷請求(INTRi = 1)時,CPU 就可以響應中斷。 ?
2.中斷響應的時間
????????很多情況下中斷請求的產生是隨機的,為了不影響 CPU 的正常工作,需要周期性地在統一的時刻由 CPU 發出中斷查詢信號,判斷當前是否有中斷請求。
????????因此 CPU 響應中斷的時間,一定是在每條指令執行階段的結束時刻;相當于在指令周期最后又加入了一個階段,這就是 中斷周期。執行周期結束后,如果有中斷請求,則 CPU 進入中斷周期;如果沒有則直接進入下一條指令的取指周期。
3.中斷響應的過程
????????CPU 響應中斷之后,就會進入中斷周期。在中斷周期 CPU 會執行一系列的操作,這些操作都是由一條 中斷隱指令 完成的。所謂的隱指令,指的是指令系統中本身沒有這條指令,它是由硬件自動完成的。具體操作如下:
(1)保護程序斷點
????????將當前 PC 的內容(程序斷點位置)保存到主存中。可以存入特定的某個地址(比如 0 地址),也可以存入堆棧中。
(2)尋找中斷服務程序的入口地址
????????在中斷周期內,可以用兩種方法尋找中斷服務程序的入口地址:硬件向量法和軟件查詢法,分別對應著硬件和軟件實現。
(3)關中斷
????????為了在響應中斷后,不受到新的中斷請求的干擾,在中斷周期需要自動做 “關中斷” 的操作,禁止 CPU 再次響應中斷請求。關中斷的具體操作就是將允許中斷觸發器 EINT 置 “0”,一般直接由硬件電路實現。
????????對應的微操作如下:
四、中斷服務程序
?1.中斷服務程序的入口地址
????????不同的中斷請求,需要執行不同的中斷服務程序。尋找中斷服務程序的入口地址,通常可以采用兩種方法:硬件向量法 和 軟件查詢法。
(1)硬件向量法
????????所謂硬件向量法,就是使用硬件直接產生一個 向量地址,再用這個向量地址找到中斷服務程序的入口地址。向量地址由中斷向量地址形成部件產生。
????????中斷向量地址形成部件的輸入,是來自排隊器的輸出 INTPi ,它的輸出則是一個二進制的 中斷向量。一般可以讓一個中斷源對應一個向量地址,因此這個部件本質上就是一個編碼器。
????????通過向量地址尋找中斷服務程序入口地址可以采用兩種方法。
?
-
在向量地址對應內存單元放一條 無條件轉移指令。這樣 CPU 響應中斷時,只要將向量地址交給 PC,然后執行這條指令,就可以跳轉到中斷服務程序入口地址了。
-
設置 向量地址表。向量地址表存放在主存中,向量地址就是對應存儲單元的地址,而存放的內容就是中斷服務程序的入口地址。
????????硬件向量法尋找入口地址速度快,現代計算機中普遍使用這種方法。
(2)軟件查詢法
????????用軟件尋找中斷服務程序入口地址的方法,就叫做軟件查詢法。各個中斷源對應的入口地址,是由程序員(或系統)預先定好、寫入程序的;可以結合軟件排隊的中斷判優,確定要響應某個中斷請求時,直接跟上一條轉移指令、跳轉至定義好的入口地址就可以了。
????????軟件查詢法不涉及硬件,更加容易維護和擴展,但查詢的時間更長。
2.中斷服務程序的流程
????????不同的中斷請求對應的中斷服務程序不同,不過它們的處理流程是類似的,一般包括 保護現場、中斷服務、恢復現場 和 中斷返回 4 個部分。
(1)保護現場
????????保護現場通常包含兩層含義:一是保存程序的斷點,這由中斷隱指令完成;二是保存通用寄存器和狀態寄存器的內容,這需要中斷服務程序完成。
????????具體操作就是在中斷服務程序的起始部分,安排幾條存數(Store)指令,將寄存器的內容全部保存到主存中;或者直接用入棧(Push)指令將寄存器內容推入棧中。
(2)中斷服務
????????中斷服務是中斷服務程序的主體部分,針對不同的中斷源,需要做出對應的操作內容。
(3)恢復現場
????????中斷服務程序的結尾部分,還需要恢復現場。對應著之前的保護現場,這一步可以用取數(Load)指令或者出棧(Pop)指令,將保存在主存中的信息恢復到寄存器中。
(4)中斷返回
????????中斷服務程序的最后一條指令,通常是一條 中斷返回指令,從而返回到原程序的斷點處繼續執行。
????????如果在 CPU 執行中斷服務程序時,又來了一個新的中斷請求,這時有兩種處理方式:一種是直接不予響應,即 CPU 在響應中斷的過程中保持 “關中斷” 狀態,直到中斷服務程序執行結束、返回之前才開中斷;另一種則是 CPU 立即響應新的中斷請求,這需要在中斷服務程序的開始階段 “開中斷”。 ?
五、中斷屏蔽技術
1.多重中斷
????????如果 CPU 在響應某個中斷請求的時候,另一個中斷源又提出了一個新的中斷請求;而 CPU 立即響應這個請求,暫停正在運行的中斷服務程序、轉而去運行新的中斷服務程序,這就是 中斷嵌套,也稱為 多重中斷。 與之對應,如果 CPU 在響應中斷時不去響應新的中斷請求,則稱為 單重中斷。
????????實現多重中斷,需要滿足兩個基本條件:
-
提前設置 “開中斷” 指令
????????由于進入中斷周期后,中斷隱指令會自動將 EINT 置為 0,因此默認會關中斷、不再響應新的中斷請求;這時如果希望處理多重中斷,就必須在中斷服務程序的開始階段設置 “開中斷” 指令來打開中斷。
-
優先級高的中斷源有權中斷優先級低的中斷源
????????只有優先級別更高的中斷源,才能打斷正在執行的中斷服務程序、優先被響應。
? ? ? ? 例如,有 A、B、C、D 四個不同的中斷源,優先級為 A > B > C > D。在 CPU 執行程序時,在某個指令周期,同時查詢到了 B、C 發來的中斷請求;之后在執行中斷服務程序的過程中,又先后查詢到了 D、A 的請求。那么如果允許多重中斷,中斷處理的時間順序如下: ?
????????中斷請求如果同時到來(比如上例中的 B、C),我們可以進行中斷判優、利用排隊器決定它們的先后順序。但對于多重循環,還需要在中斷響應過程中繼續判斷優先級、決定是否可以打斷當前的中斷服務程序。這是通過 中斷屏蔽技術 來實現的。
2.中斷屏蔽觸發器
? ? ? ?為 了實現對每個中斷源的屏蔽,可以在中斷請求觸發器 INTR 之前增設一個 中斷屏蔽觸發器 MASK。當 MASK 為 “1” 時,表示該中斷源被屏蔽,中斷請求不被響應。
????????屏蔽觸發器同樣既可以設置在接口電路中、也可以直接集成在 CPU 內。以 I/O 設備作為中斷源為例,I/O 設備的接口電路中會有一個 完成觸發器 D,它為 “1” 則表示設備已經處于就緒狀態、要向 CPU 發出中斷請求了。一般情況下,D 的輸出可以直接接到中斷請求觸發器 INTR 的輸入;現在則可以與 MASK 的輸出經與非門之后、再交給 INTR。
????????這樣,當設備已經準備就緒(D = 1),且設備未被屏蔽(MASK = 0)時,來自 CPU 的中斷查詢信號就會將 INTR 置 “1”,表示該設備發出了中斷請求信號。
????????同樣,排隊器內也可以加上屏蔽條件,就組成了具有屏蔽功能的排隊器。例如集成在 CPU 內的排隊器如果加上屏蔽功能,只需要另外將屏蔽信號也接入與非門就可以了:
?
3.屏蔽字和屏蔽技術
????????顯然,對于每個中斷源,中斷請求觸發器 INTR 和 中斷屏蔽觸發器 MASK 都是成對出現的。如果將所有屏蔽觸發器組合在一起,也可以構成一個 屏蔽寄存器。屏蔽寄存器的內容就稱為 屏蔽字。
????????屏蔽字可以在中斷服務程序中進行設置,屏蔽字和中斷源的優先級是一一對應的。以 16 個中斷源 I1 ~ I16 的屏蔽字為例,每個屏蔽字都是 16 位:
????????在不同中斷源的中斷服務程序中,可以設置適當的屏蔽字,就能對優先級不同的中斷源進行屏蔽。
????????例如,在 I~1~ 的服務程序中,將屏蔽字設為全 1,就表示它的優先級最高:在響應 I~1~ 中斷請求的過程中,不會再去響應任何新的請求(包括 I~1~ 自己發來的);這相當于就是單重中斷。而對于 I~3~ ,在服務程序中將屏蔽字前兩位設為 0、后面為 1,表示 I~1~、I~2~ 優先級更高、不被屏蔽,而后面的中斷源(包括自己)被屏蔽;于是開中斷之后,I~1~、I~2~ 發來的新中斷請求就可以打斷當前 I~3~ 的中斷服務程序,實現了多重中斷。
4.改變處理優先級
????????使用屏蔽技術還可以改變中斷源的優先等級。中斷源的優先級,包括兩層含義:響應優先級 和 處理優先級。
-
響應優先級:CPU 響應各中斷源請求的先后次序,跟排隊器有關,一般是硬件線路設定好的,不易改動;
-
處理優先級:CPU 實際執行中斷服務程序的先后次序,可以通過屏蔽技術進行改動。
????????如果不采用屏蔽技術,那么處理的優先順序就是按照響應優先級來的。例如,A、B、C、D 四個中斷源,優先級別為 A > B > C > D,根據這一次序設計出排隊器之后,當它們同時發來中斷請求時,處理順序就是響應順序:
????????如果采用了屏蔽技術,就可以在不改變響應順序的前提下,改變 CPU 處理中斷的順序。假如我們希望將它們的處理次序改為 A → D → C → B,那么每個中斷源的中斷服務程序中應該重新設置屏蔽字:
????????這樣,同樣還是 A、B、C、D 同時發出中斷請求,這時的處理順序就會變為:
????????顯然,采用屏蔽技術改變處理優先級,需要在中斷服務程序中重置屏蔽字。這樣,中斷服務程序的處理流程就會變為: ?
????????跟之前相比,增加了 置屏蔽字 和 恢復屏蔽字 兩步操作。而為了防止在恢復階段又出現新的中斷,需要先關中斷、等到恢復現場和屏蔽字之后再次開中斷。