x86异常处理与中断机制(2)中断向量表
補(bǔ)充:事件不僅包含中斷和異常,還包含系統(tǒng)調(diào)用,這個屬于用戶主動請求的事件。
上一節(jié),只有一個溢出異常,那么,如果很多異常、中斷呢?(中斷向量表)
另外,之前0號地址只能存儲兩條指令,如果需要更多指令怎么辦?(地址的位置以及對應(yīng)程序大小應(yīng)該更靈活)
注意,中斷服務(wù)程序包含(保存現(xiàn)場,調(diào)用處理方法(主體),恢復(fù)現(xiàn)場)
我們在遇到中斷之后,需要執(zhí)行的步驟,我們簡化一下
在不同的時代,中斷的處理都是這個過程,只不過每個過程具體的執(zhí)行發(fā)生了變化,且越來越復(fù)雜,我們依次看一下。
1 時代1:UNIVAC時代,僅有固定地址中斷處理
在最初的計算機(jī)時代,只有很少的內(nèi)部中斷和外部中斷。
內(nèi)個時候的中斷服務(wù)程序,是固定的地址,并且程序的大小也相對受限。
例如出現(xiàn)了算數(shù)溢出,那么就會跳轉(zhuǎn)到地址0執(zhí)行中斷服務(wù)程序。
不僅如此,這個時候的中斷服務(wù)程序幾乎是
- 固定地址
- 固定大小
因此靈活性很差,不過由于很少,所以還好。
到了后來,中斷越來越多,因此就有了中斷向量表,下面看看8086時代吧。
2 時代2:8086時代,實(shí)模式 + 中斷向量表
這個時代,中斷已經(jīng)較多了,管理中斷的方式也更加靈活了。
8086采用的是實(shí)模式,也就是說,進(jìn)入CPU指令中的地址,就是實(shí)際的物理地址。
在8086的1MB內(nèi)存中,有專門的中斷向量表區(qū),從地址0開始的1K字節(jié),它用于存放中斷服務(wù)程序的地址,也就是存放CS:IP。
每對CS:IP占用4個字節(jié),因此1KB的空間,最多可以支持256種中斷。
CS:IP,CS在前,IP在后,因此CS在高地址,IP在低地址,又因?yàn)槭切《四J?#xff0c;因此IP的高字節(jié)是高位,低字節(jié)是低位;CS同理。
這樣一來,實(shí)際的中斷服務(wù)程序的位置,是根據(jù)這些CS:IP的值確定的,而它們在內(nèi)存中是可以修改的,因此
- 中斷服務(wù)程序的位置可變
- 程序的大小可改
并且這些中斷服務(wù)程序的位置是任意的,只要能夠與中斷向量表對應(yīng)上即可。
同時,不同的中斷服務(wù)程序,位置沒有關(guān)聯(lián),放哪里都行。在實(shí)模式的8086之下,只需要CS:IP就可以確定實(shí)際內(nèi)存的位置。
在這個時代,中斷服務(wù)程序的位置了大小更加靈活,變成了間接獲取,因?yàn)榧恿艘粋€中斷向量表。
注意,這個時候有5種類型的中斷,并不是5個中斷,這個時候涉及到的內(nèi)部中斷有4個,外部中斷有1個,而這個外部中斷,是8259A芯片發(fā)出的,該芯片外面可以連接很多個外設(shè)。
我們來看看這個時代中斷處理的示意圖。
3 時代3:80386時代,保護(hù)模式 + 中斷向量表
這個時代就有點(diǎn)復(fù)雜了,引入了保護(hù)模式,同時增加了一些中斷類型,這也是Linux 0.11內(nèi)核對應(yīng)的CPU。
圈住的部分是80386支持的中斷類型,int0 ~ int16,其中int15未定義,可以在手冊中查到。
3.1 保護(hù)模式下的尋址方式
首先,保護(hù)模式下,依然是CS:EIP的形式,但是由于EIP已經(jīng)足夠?qū)ぶ?GB,因此CS不再作為位數(shù)擴(kuò)展的功能了,它的功能發(fā)生了改變。
在保護(hù)模式下,段寄存器依然是16位,它們變成了段選擇子寄存器,先從最簡方式描述地址的生成方法:
是不是比實(shí)模式復(fù)雜多了,下面,進(jìn)一步展開細(xì)節(jié)。
通過段選擇子寄存器(此后均以CS舉例說明),怎么找到對應(yīng)的段描述符?
在保護(hù)模式下, CS + GDTR獲取對應(yīng)的描述符(0~8191),這樣,我們就獲取了代碼段的描述符了。
接下來我們看看這個描述符
它有8個字節(jié)的大小,其中有四個字節(jié)是段基址,就是這個段基址與EIP組合,形成最終的要訪問內(nèi)存的(虛擬)地址。其他的自己還涉及到權(quán)限以及界限,先不管是干啥的。
段描述符的內(nèi)容是什么,怎么獲取段基址
上面已經(jīng)說明了。
3.2 保護(hù)模式下的中斷操作
上面一小節(jié),經(jīng)歷了一系列復(fù)雜過程,終于說明了保護(hù)模式下如何尋址,真的很復(fù)雜啊……下面說明一下中斷操作過程。其實(shí)最主要說明的還是找中斷服務(wù)程序位置這個過程。
在保護(hù)模式下,也有一個IDTR中斷描述符表寄存器,還有一個IDT中斷描述符。
這個IDT同樣是支持256種類型的中斷的,每個描述符表項(xiàng)占8個字節(jié),因此一共占用2KB。
IDTR提供的是IDT的基址,然后CPU獲取中斷號之后,根據(jù)中斷號 * 8 + IDTR定位對應(yīng)的描述符。
對于中斷描述符
- 字節(jié)0167四個字節(jié)對應(yīng)的是32位地址,也就是EIP的值
- 字節(jié)23對應(yīng)的是CS的值
- 有了CS:EIP就可以通過上一小節(jié)的方式找到對應(yīng)的地址,從而找到中斷服務(wù)程序入口地址
(這個過程其實(shí)與CS:IP類似,只不過麻煩了點(diǎn))
折騰了這么一大圈,終于找到中斷服務(wù)程序了……
3.3 小結(jié)
這個太復(fù)雜了,我們簡單總結(jié)一下吧。
首先,保護(hù)模式下的尋址方式更復(fù)雜了,引入了全局描述符表,雖然依然是CS:EIP,但是其計算方式更加復(fù)雜了。
其次,保護(hù)模式下的中斷處理更復(fù)雜了
- 以前固定位置的中斷向量表,變成了任意位置的中斷描述符表IDT,通過IDTR和中斷類型號計算得到中斷描述符
- 再通過中斷描述符的內(nèi)容獲取CS:EIP,再獲取對應(yīng)中斷服務(wù)程序的入口地址
我們可以看到,模式越來越復(fù)雜,間接程度越來越高,設(shè)置的自由度提高,安全性也提高了。
思想:太固定死板怎么辦?加個固定的中轉(zhuǎn)站!通過改變中轉(zhuǎn)站,來實(shí)現(xiàn)靈活地分配目標(biāo)
這幾個時代的發(fā)展過程,可以說中轉(zhuǎn)站越來越多,越來越復(fù)雜,靈活度越來越高。
小結(jié)
本篇內(nèi)容,貫徹的是中斷處理的找中斷服務(wù)程序的過程。
可以看到
不管怎樣,時代的發(fā)展使得根據(jù)中斷類型號,找到中斷服務(wù)程序這個過程越來越復(fù)雜,靈活度也越來越高。
后面會介紹中斷處理的其他過程,最后結(jié)合Linux 0.11內(nèi)核源代碼,使得軟硬件對應(yīng)上。
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的x86异常处理与中断机制(2)中断向量表的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【C language】动态数组的创建和
- 下一篇: x86异常处理与中断机制(3)中断处理过