Linux的中斷和系統調用 & esp、eip等寄存器


http://www.linuxidc.com/Linux/2012-11/74486.htm

一共三篇

 

中斷一般分為三類

1、由計算機硬件異常或故障引起的中斷,稱為內部異常中斷;

2、由程序中執行了引起中斷的指令而造成的中斷,稱為軟中斷(這也是和我們將要說明的系統調用相關的中斷);

3、由外部設備請求引起的中斷,稱為外部中斷。簡單來說,對中斷的理解就是對一些特殊事情的處理。

 

當發生軟件中斷時,其他所有的中斷都可能發生並被處理;但當發生磁盤中斷時,就只有時鍾中斷和機器錯誤中斷能被處理了。

 

用戶態和核心態之間的區別是什么呢?(以下區別摘至《UNIX操作系統設計》)

1、用戶態的進程能存取它們自己的指令和數據,但不能存取內核指令和數據(或其他進程的指令和數據)。然而,核心態下的進程能夠存取內核和用戶地址

2、某些機器指令是特權指令,在用戶態下執行特權指令會引起錯誤

對此要理解的一個是,在系統中內核並不是作為一個與用戶進程平行的估計的進程的集合,內核是為用戶進程運行的。

 

內核自己的棧這在最上層的1G的地址空間內,這是只能由內核訪問的部分。

 

http://www.cnblogs.com/txlstars/p/5401033.html

用戶態:Ring3運行於用戶態的代碼則要受到處理器的諸多檢查,它們只能訪問映射其地址空間的頁表項中規定的在用戶態下可訪問頁面的虛擬地址,且只能對任務狀態段(TSS)中I/O許可位圖(I/O Permission Bitmap)中規定的可訪問端口進行直接訪問。

內核態:Ring0在處理器的存儲保護中,核心態,或者特權態(與之相對應的是用戶態),是操作系統內核所運行的模式。運行在該模式的代碼,可以無限制地對系統存儲、外部設備進行訪問。

 

二、什么情況下會發生從用戶態向內核態切換。這里細分為3種情況。

1、發生系統調用時

      這是處於用戶態的進程主動請求切換到內核態的一種方式。用戶態的進程通過系統調用申請使用操作系統提供的系統調用服務例程來處理任務。而系統調用的機制,其核心仍是使用了操作系統為用戶特別開發的一個中斷機制來實現的,即軟中斷。

2、產生異常時

      當CPU執行運行在用戶態下的程序時,發生了某些事先不可知的異常,這時會觸發由當前運行的進程切換到處理此異常的內核相關的程序中,也就是轉到了內核態,如缺頁異常。

3、外設產生中斷時

      當外圍設備完成用戶請求的操作后,會向CPU發出相應的中斷信號,這時CPU會暫停執行下一條即將要執行的指令轉而去執行與中斷信號對應的處理程序,如果先前執行的指令是用戶態下的程序,那么這個轉換的過程自然也就發生了由用戶態到內核態的切換。比如硬盤讀寫操作的完成,系統會切換到硬盤讀寫的中斷處理程序中執行后續操作等。    
       可以看到上述三種由用戶態切換到內核態的情況中,只有系統調用是進程主動請求發生切換的,中斷和異常都是被動的。

 

具體的切換操作,涉及的關鍵步驟是完全一致的,沒有任何區別。

涉及到由用戶態切換到內核態的步驟主要包括:

[1] 從當前進程的描述符中提取其內核棧的ss0及esp0信息。

[2] 使用ss0和esp0指向的內核棧將當前進程的cs,eip,eflags,ss,esp信息保存起來,這個過程也完成了由用戶棧到內核棧的切換過程,同時保存了被暫停執行的程序的下一條指令。

[3] 將先前由中斷向量檢索得到的中斷處理程序的cs,eip信息裝入相應的寄存器,開始執行中斷處理程序,這時就轉到了內核態的程序執行了。

 

關於esp, eip

http://blog.csdn.net/chenlycly/article/details/37912417

1. EIP寄存器里存儲的是CPU下次要執行的指令的地址。
 也就是調用完fun函數后,讓CPU知道應該執行main函數中的printf("函數調用結束")語句了。
2. EBP寄存器里存儲的是是棧的棧底指針,通常叫棧基址,這個是一開始進行fun()函數調用之前,由ESP傳遞給EBP的。(在函數調用前你可以這么理解:ESP存儲的是棧頂地址,也是棧底地址。)
3. ESP寄存器里存儲的是在調用函數fun()之后,棧的棧頂。並且始終指向棧頂。
 
等到調用結束,EBP會把其地址再次傳回給ESP。所以ESP又一次指向了函數調用結束后,棧頂的地址。
 
更多關於 寄存器的內容,需要看這里:

4個數據寄存器(EAX、EBX、ECX和EDX)
2個變址和指針寄存器(ESI和EDI) 2個指針寄存器(ESP和EBP)
6個段寄存器(ES、CS、SS、DS、FS和GS)
1個指令指針寄存器(EIP) 1個標志寄存器(EFlags)

 

32位CPU有4個32位的通用寄存器EAX、EBX、ECX和EDX。對低16位數據的存取,不會影響高16位的數據。這些
低16位寄存器分別命名為:AX、BX、CX和DX,它和先前的CPU中的寄存器相一致。

寄存器AX和AL通常稱為累加器(Accumulator),用累加器進行的操作可能需要更少時間。累加器可用於乘、
除、輸入/輸出等操作,它們的使用頻率很高;
寄存器BX稱為基地址寄存器(Base Register)。它可作為存儲器指針來使用; 
寄存器CX稱為計數寄存器(Count Register)。在循環和字符串操作時,要用它來控制循環次數;在位操作
中,當移多位時,要用CL來指明移位的位數;
寄存器DX稱為數據寄存器(Data Register)。在進行乘、除運算時,它可作為默認的操作數參與運算,也
可用於存放I/O的端口地址。

 

2、變址寄存器

32位CPU有2個32位通用寄存器ESI和EDI。它們主要用於存放存儲單元在段內的偏移量,
用它們可實現多種存儲器操作數的尋址方式,為以不同的地址形式訪問存儲單元提供方便。

 

CPU內部的段寄存器:

CS——代碼段寄存器(Code Segment Register),其值為代碼段的段值;
DS——數據段寄存器(Data Segment Register),其值為數據段的段值;
ES——附加段寄存器(Extra Segment Register),其值為附加數據段的段值;
SS——堆棧段寄存器(Stack Segment Register),其值為堆棧段的段值;
FS——附加段寄存器(Extra Segment Register),其值為附加數據段的段值;
GS——附加段寄存器(Extra Segment Register),其值為附加數據段的段值。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM