開篇
異常這個名詞應該大家都不陌生,很多人都聽說過。系統調用知道吧?其實系統調用也是一種異常。但是具體的什麼是異常呢?他在電腦中有什麼作用?他是如何工作,如何被我們利用的?我想很多人都還不都是很清楚。、
瞭解異常有諸多好處,可以讓你更好的理解作業系統和應用程式的互動,更好的理解並發等。
所以今天就簡單的來說一下異常。
註:本博文圖片來源《Computer system-A Programmer's Perspective》
什麼是異常
為了便於理解,我就不按照書本來了啊,異常可以這樣理解:
電腦執行一個連續的指令序列,如:a1,a2,a3,,,ak,這些指令執行的時候是順序執行的,相鄰的兩條指令ak,ak+1在儲存中也是相鄰的,也就是說他們是一個平滑的指令流。
而有時候這種指令流會發生突變,也就是說相鄰執行的兩條指令ak,ak+1在儲存空間中是不相鄰的。造成這種突變的可能有:跳轉,函數調用,返回等。今天我們所討論的異常,也是造成這種指令流突變的原因之一。
所以異常可以認為是指令順序執行的時候,突然跳轉到別的地方執行指令。
現在就可以來看相對專業的說法了:異常是控制流程中的突變,用來相應處理器狀態中的某些變化。
可以通過來更好的理解上述內容:
那麼異常處理結束後電腦中的指令如何繼續往下執行呢?根據觸發異常的種類,會有三種情況:
1)處理常式將控制返回給當前指令I currr,即當事件發生時正執行的指令。
2)將控制返回給下一條指令,即如果沒有發生異常的下一條指令。
3)終止發生異常的程式。
異常處理
現在應該基本搞懂什麼是異常了吧,發生了異常,總不能就不管吧,呵呵,有異常總是要處理的。這個部分就簡單的說一下異常處理。
按照上面所說的,異常是在指令順序執行的時候由於某些突發情況指令跳到其他地方執行。注意上面說的是“跳到其他地方執行”所以說,異常處理也是通過固定的程式碼來實現的。至於具體的怎麼實現,我們並不關心,這裡要關注的是控制是如何從發生異常的程式跳轉到處理常式的。
系統中為可能的每種異常都分配了一個唯一的非負數異常號。每個異常號記錄了處理該異常的代碼。這些資料被放在一個稱為異常表的結構裡,當系統初始化的時候會初始化這個表。所以當發生異常的時候,對應於異常表中的那個異常號,就能定位到具體的例外處理常式了。
下面是一個異常表:
在系統運行時,如果發生一個異常,系統檢測得到其異常號,通過異常號,就能確定要處理的異常,同時也確定了處理異常的程式地址。異常號是到異常表的一個索引,相當於一個異常號就對應於異常表中的一項。異常表的起始地址放在一個異常表基寄存器的特殊cpu寄存器裡。下面是一個產生例外處理常式地址的過程:
通過異常號和基址確定了異常表中的一個項,從而確定例外處理常式的地址。
異常的類別
什嗎?異常還有類別?。。。是的,在運行過程中會發生各種各樣的異常,所以就把他們分為四類:中斷(interrupt)陷阱(trap)故障(fault)終止(abort)
下面就簡單的說一下吧:
中斷:
中斷是非同步發生的,是來自處理器外部的I/O裝置的訊號的結果。為什麼是非同步呢?硬體中斷不是由任何一條指令造成的,從這個意義上說是非同步。硬體中斷的例外處理常式通常也叫中斷處理常式。
中所示,中斷處理常式完成時,他將控制返回給下一條指令(即如果沒有發生中斷,在控制流程中當前指令之後的一條指令)結果是程式繼續執行,就好像沒發生中斷一樣。
陷阱和系統調用
系統調用應該很多人都知道,而且經常在用,其實系統調用也是異常的一種,他是”有意“的異常。
就像中斷處理常式一樣,設陷處理常式將程式控制返回到下一條指令。陷阱最重要的作用是在使用者程式和核心之間提供一個像程序呼叫一樣的介面,叫做系統調用。
使用者程式經常要像核心請求服務,比如讀一個檔案(read)建立一個進程(fork)載入以新的程式(execve)等。為了讓使用者程式實現這些功能,處理器提供了一條特殊的“system call n ”指令。執行system call 指令會導致一個到例外處理常式的陷阱,這個程式對參數n 進行解碼,並調用適當的核心程式。
具體的過程如所示:
:設陷處理常式將程式控制返回到下一條指令.
關於系統調用和函數調用的區別可參見前一篇文章:
linux系統調用和庫函數調用的區別
故障:
故障由錯誤情況引起,它能夠被故障處理常式修正。當故障發生時,處理器將控制轉移給故障處理常式。如果能修複錯誤,返回到引起故障的指令,重新執行它,否則終止引起故障的程式(調用abort)。
一個經典的故障處理常式是頁缺異常。當引用到一個虛擬位址,而與該地址對應的物理頁面不在儲存空間中,必須從磁碟中取出,就會發生故障。故障處理常式(這裡是頁缺處理常式)會將頁面從磁碟中載入到記憶體中,把控制返回給引起故障的指令重新執行。當指令再次執行時,相應的物理頁面已經在記憶體中了,指令便可以沒有故障的運行。
終止:
終止是不可恢複的致命錯誤造成的結果,通常是一些硬體錯誤。終止處理常式不會吧控制返回給引起異常的程式,處理常式會將控制返回給一個abort,然後終止這個應用程式。
小結
這篇博文內容較少,理解起來也比較容易。異常在電腦中是很重要的一個概念,關於異常的東西還有很多需要學習。遇到不懂的東西,之前很喜歡google,把要搜的東西翻譯為英文然後在美國的伺服器搜,各種搜尋。慢慢的覺得這種學習方式還是欠妥的,上網擷取知識的速度確實是很快,可是知識的品質就參差不齊了,對於一個知識點的理解很難在網上找到滿意的解(這個或許大家也感同身受吧)相反,看書擷取知識相對慢一些,卻能得到高品質的知識。所以當你對一系列的知識點模糊不清的時候,我覺的看書的最好的。當然了,看書得看經典書。何為經典書?我認為:1)在某方面的知識點全面。2)語言方面通俗易懂。3)合理的安排了學習順序。
這篇博文參考了《深入理解電腦系統》,我是第二次看這個書,感覺還是很有收穫。
本書英文版:http://ishare.iask.sina.com.cn/f/24228232.html
全文完,不足之處望不吝賜教!
參看資料:computer systems
如有轉載請註明出處:http://www.cnblogs.com/yanlingyin/
一條魚、尹雁鈴@ 部落格園 2012-5-05
E-mail:yanlingyin@yeah.net