1、異常
1.1、什么是異常?
異常是控制流中的突變,用來響應處理器狀態中的某些變化,一部分由硬件實現 一部分由軟件
每次從一條指令過渡到另外一條指令的過程稱為控制轉移,這樣的一個控制轉移序列叫做控制流,如果每條指令都是相鄰的,這樣的過渡就是平滑序列。如果一條指令與另外一條指令不相鄰,這樣突發性的過渡稱為異常,也就是我們這一章要學到的異常控制流(Exceptional Contro Flow)。
處理完異常后,有三種結果:
- 將控制交給發生異常前的指令
- 將控制交給將執行的嚇一條指令
- 終止被中斷的程序
1.2、異常的種類
異常可以分為四類:中斷(interrupt)、陷阱(trap)、故障(fault)和終止(abort)。
-
中斷
中斷是**異步**發生的,是來自處理器外部的I/O設備(如網絡適配器、磁盤控制器和定時器芯片)的信號的結果。
硬件中斷不是由任何一條專門的指令造成的,從這個意義上來說,它是異步的。
硬件中斷的處理程序常常稱為中斷處理程序(interrupt handler)
image -
陷阱
陷阱是有意的異常,是執行一條指令的結果。就像中斷處理程序一樣,陷阱處理程序將控制返回到下一條指令。
陷阱最重要的用途是在用戶程序和內核之間提供一個像過程一樣的接口,叫做系統調用。
-
故障
故障是由錯誤情況引起的,它**可能能夠被故障處理程序修正**。 當故障發生時,處理器將控制轉移給故障處理程序。如果處理程序能夠修正這個錯誤情況,它就將控制返回到引起故障的指令,從而重新執行它。否則,處理程序返回到內核中的abort例程,abort例程會終止引起故障的應用程序。
-
終止
終止是不可恢復的致命錯誤造成的結果,通常是一些硬件錯誤,比如DRAM或者SRAM位被損壞時發生的奇偶錯誤。終止處理程序從不將控制返回給應用程序。

1.3、異常處理
當操作系統啟動時會生成一張異常表,存放著每一種異常處理程序的地址。
當處理器觸發異常后,會拿異常號去異常表中查找生成異常處理程序的地址。
https://img-blog.csdnimg.cn/20200818094039419.png#pic_center
異常表的起始地址放在異常表基址寄存器中。
過程調用時,在跳轉到處理程序之前,處理器將返回地址壓入棧中。
2、進程
2.1、什么是進程?
異常是允許操作系統內核提供進程(process)概念的基本構造塊。進程是計算機科學中最成功、最深刻的概念之一。
進程的經典定義就是一個執行中程序的實例。
系統中的每個程序都運行在某個進程的上下文(context)中。上下文是由程序正確運行所需的狀態組成的。這個狀態包括存放在內存中的程序的代碼和數據,它的棧、通用目的寄存器的內容、程序計數器、環境變量以及打開文件描述符的集合。
2.2、邏輯控制流
即使在系統中通常有許多其他程序在運行,進程也可以向每個程序提供一個假象,好像它在獨占地使用處理器。如果想要調試器單步執行程序,我們會看到一系列的程序計數器(PC)的值,**這些值唯一地對應于包含在程序的可執行目標文件中的指令**,或是包含在運行時動態鏈接到程序的共享對象中的指令。**這個PC值的序列叫做邏輯控制流,或者簡稱邏輯流**。
2.3、并發流
一個邏輯流的執行在時間上與另一個流重疊,稱為并發流(concurrent flow),這兩個流被稱為并發地運行。
多個流并發地執行的一般現象稱為并發(concurrent)。一個進程和其他進程輪流運行的概念稱為多任務(multitasking)。一個進程執行它的控制流的一部分的每一時間段叫做時間片(time slice)。因此,多任務也叫做時間分片(time slicing)。
注意,并發流的思想與流運行的處理器核數或計算機數無關。**如果兩個流在時間上重疊,那么它們就是并發的,即使它們是運行在同一個處理器上**。不過,有時我們會發現,確認并行流是很有幫助的,它是并發流的一個真子集。**如果兩個流并發地運行在不同的處理器核或者計算機上,那么我們稱它們為并行流(parallel flow)**,它們并行地運行,且并行地執行。
2.4、上下文切換
操作系統內核使用一種稱為上下文切換(context switch)的較高層形式的**異常控制流來實現多任務**。內核為每個進程維護一個上下文(context)。**上下文就是內核重新啟動一個被搶占的進程所需的狀態**,它由一些對象的值組成,這些對象包括通用目的寄存器、浮點寄存器、程序計數器、用戶棧、狀態寄存器、內核棧和各種內核數據結構,比如描述地址空間的頁表、包含有關當前進程信息的進程表,以及包含進程已打開文件的信息的文件表。
**在進程這些的某些時刻,內核可以決定搶占當前進程,并重新開始一個先前被搶占的進程。這種決策就叫做調度(scheduling)**,是由內核中稱為調度器(scheduler)的代碼處理的。當內核選擇一個新的進程運行時,我們說內核調度了這個進程。在內核調度了一個新的進程運行后,它就搶占當前進程,并使用一種稱為上下文切換的機制來將控制轉移到新的進程。
上下文切換的步驟:
1)保存當前進程的上下文。
2)恢復某個先前被搶占的進程被保存的上下文。
3)將控制傳遞給這個新恢復的進程。