1. 程式人生 > 其它 >C++:18---const關鍵字(附常量指標、指標常量、常量指標常量)

C++:18---const關鍵字(附常量指標、指標常量、常量指標常量)

異常

什麼是異常

異常是異常控制流的一種形式,它一部分由硬體實現,一部分由作業系統實現。因為它們有一部分是由硬體實現的,所以具體細節將隨系統的不同而有所不同。然而,對於每個系統而言,基本的思想都是相同的。

大致如下:
在這裡插入圖片描述

異常控制流

下述程式中的write和_exit函式就進行了系統函式的呼叫:

// hello world
int main()
{
 	write(1, "hello, world\n", 13);
	_exit(0);
}

其對應的彙編為:

.section .data
 	string:
 		.ascii "hello, world\n"
 	string_end:
		.equ len, string_end - string
 	.section .text
 	.globl main
main:
	First, call write(1, "hello, world\n", 13)
	movq 	$1, %rax 	  write is system call 1
	movq 	$1, %rdi 	  Arg1:stdout has descriptor 1
	movq 	$string, %rsi Arg2:Hello world string
	movq 	$len, %rdx    Arg3:string length
	syscall     	  Make the system call
	Next, call exit(0)
	movq 	$60, %rax 	  _exit is system call 60
	movq 	$0, %rdi      Arg1:exit status is 0
	syscall 		  Make the system call

作業系統的系統呼叫,在彙編中是使用暫存器進行引數傳遞

與過程之間的引數呼叫類似,作業系統的系統呼叫,同樣使用了6個暫存器來傳遞引數,但暫存器的使用與caller的有所不同。作業系統的系統呼叫,使用了%rdi,%rsi,%rdx,%r10,%r8,%r9這六個暫存器,並以%rax作為返回值

處理器的狀態:在CPU中有狀態暫存器,會標識處理器的狀態。處理器的狀態一旦發生重要變化,則稱之為事件。事件會發出請求訊號,以告訴CPU,稱之為中斷請求。處理中斷請求——由事件引起了異常,使控制流發生了變化。原本控制流應該是在執行使用者寫的程式,而發生異常後,去執行了另外的程式——異常處理程式。

事件並不一定與當前執行的指令有關。例如,訪問時發現數據不在記憶體中時,就引起了異常,由異常處理程式將需要的資料從輔存調往主存,這是與執行有關的事件。而ctrl+C強制中斷,則與當前執行的指令無關。

異常處理程式屬於作業系統的一部分。一旦執行完處理程式後,還要回到原來的程式碼中繼續執行。返回的位置根據執行的結果而定,
  1、可能會回到引起異常的指令上,重新執行,
  2、也可能會返回到引起異常的指令的下一條指令。當前指令執行完後,停下來去執行異常處理程式,寫入到CPU中。
  3、還可能是程式完全被中斷(例如藍屏、宕機),此時機器出了問題,異常處理程式已經解決不了了

異常表

異常的編號從0——255,每個編號對應一個異常處理程式。在作業系統中,專門有一張稱為異常表的表(有時也稱作中斷向量表),一共有256項。每個表項中存放的是對應的異常處理程式的入口地址。這張表是常駐記憶體的,由專有暫存器去找到那個表

在64位機下,每次都是將異常編號乘以8來找到對應的地址

核心棧

異常處理程式執行在核心模式下,可以訪問所有資源。核心棧中儲存了能夠幫助程式恢復執行的資訊,例如:返回地址、當前條件碼

包括滑鼠、鍵盤的互動,都是通過異常執行的

Linux:異常
Windows:中斷

常見異常

同步異常:與程式的執行息息相關

被執行的指令所引起的事件(自己願意引起的異常)

包括:

陷阱:跟蹤時設定的斷點,稱之為陷阱(程式執行到斷點時的停止)。會返回到下一條指令

故障:例如頁故障(嘗試找到某一頁,發現不在記憶體中,這個故障是可以修復的)、保護故障(訪問時發現越界了——只允許在某個記憶體範圍內訪問,但卻超出了這個範圍,導致訪問被拒絕)

中斷/終止:藍屏(檢查到記憶體出現問題等)、宕機等

每一個異常,都是有對應的編號的。其中,0-31對應了固定的異常,而從32開始則是自定義異常。
  
常見的同步異常:除數為0異常、保護異常、頁故障、機器檢測問題、其他異常(從32號開始,都是任意定義的,而32號之前的則是固定的)