天天看點

彙編語言-内中斷

中斷

中斷的意思是指CPU不在接着(剛執行的指令)向下執行,而是轉去處理這個特殊資訊,而這個特殊的資訊我們可以稱其為中斷資訊。中斷資訊是要求CPU馬上進行某種處理,并向所要進行的該種處理提供了必備的參數的通知資訊。

内中斷的産生

對于8086CPU,當CPU内部有下面的情況發生的時候,将産生響應的中斷資訊。

  • 除法錯誤,比如,執行div指令産生的除法溢出;
  • 單步執行;
  • 執行into指令;
  • 執行int指令。

而中斷資訊中必須包含中斷類型碼的資料來辨別終端資訊的來源。中斷類型碼為一個位元組型資料,可以表示256種中斷資訊的來源。

在8086CPU中的終端類型碼如下。

  • 除法錯誤:0
  • 單步執行:1
  • 執行into指令:4
  • 執行int指令,該指令的格式為int n,指令中的n為位元組型立即數,是提供給CPU的中斷類型碼。

中斷處理程式

我們編寫的,用來進行中斷資訊的程式被稱為中斷處理程式。

要想執行中斷處理程式如何從8位終端類型碼得到處理程式的段位址和偏移位址呢?

中斷向量表

  • 中斷向量就是中斷處理程式的入口位址。
  • 中斷向量表就是中斷處理程式入口位址的清單。

中斷向量表在記憶體0000:0000到0000:03FF的1024個單元中儲存,其中存放着256個中斷資訊的來源所對應的中斷處理程式的入口,這個入口位址包括段位址和偏移位址,是以一個表項占兩個位元組,高位址字存放段位址,低位址字存放偏移位址。CPU隻要知道了中斷類型碼,就可以将中斷類型碼作為中斷向量表的表項号,定位相應的表項,進而得到中斷處理程式的入口位址。

中斷過程

中斷過程就是用中斷類型碼找到中斷向量,并用它設定CS和IP的過程。

下面是8086CPU在收到中斷資訊後,所引發的中斷過程。

  • (從中斷資訊中)取得中斷類型碼;
  • 标志寄存器的值入棧(因為在中斷過程中要改變标志寄存器的值,是以先将其儲存在棧中);
  • 設定标志寄存器的第8位TF和第9位IF的值為0;
  • CS的内容入棧;
  • IP的内容入棧;
  • 從記憶體位址為中斷類型碼4和中斷類型碼4+2的兩個子單元中讀取中斷處理程式的入口位址設定IP和CS。

更簡潔的表述中斷過程,如下:

取得中斷類型碼 N;
pushf
TF=0,IF=0
push CS
push IP
(ip)=(N*4),(CS)=(N*4+2)
           

中斷處理程式和iret指令

中斷處理程式的編寫方法和子程式的比較相似,下面是正常的步驟:

  • 儲存用到的寄存器;
  • 進行中斷;
  • 恢複用到的寄存器;
  • 用iret指令傳回。

iret指令的功能用彙編文法描述為:

pop ip
pop cs
popf
           

iret通常和硬體自動完成的中斷過程配合使用。中斷過程中,寄存器入棧的順序和iret剛好相對應。

編寫處理0号中斷

;因為除法溢出随時可能發生,CPU随時都可能将CS:IP隻想程式的入口,執行程式,是以我們将程式放入記憶體中。
;因為系統要處理的中斷事件遠沒有達到256個,是以在中斷向量表中,有許多單元是空的。

assume cs:code

code segment
start:

;安裝:将中斷處理程式代碼送入中斷向量表中。
    mov ax,cs
    mov ds,ax
    mov si,offset do0   ;ds:si指向源位址

    mov ax,0
    mov es,ax
    mov di,200h         ;es:di指向目的位址
    mov cx,offset do0end-offset do0 ;設定cx為傳輸長度 ;-是編譯器識别的運算符号,編譯器可以用它來進行兩個常數的減法。
    cld		;設定傳輸方向為正
    rep movsb
    
;設定中斷向量:将do0的入口位址,寫入中斷向量表的0号表項中,使do0為0号中斷的中斷處理程式
    mov ax,0
    mov es,ax
    mov word ptr es:[0*4],200h
    mov word ptr es:[0*4+2],0

    mov ax,4c00h
    int 21h
    
;中斷處理程式代碼
    do0: jmp short do0start 
        db "overflow!"  ;放在data段執行完後記憶體被系統釋放資料可能被覆寫

    do0start:
        mov ax,cs
        mov ds,ax
        mov si,202h     ;ds:si指向字元串,複制到0:200處
		
        mov ax,0b800h
        mov es,ax
        mov di,12*160+36*2  ;顯示位置

        mov cx,9
        s:
            mov al,[si]
            mov es:[di],al
            inc si
            add di,2
            loop s
        mov ax,4c00h
        int 21h
    do0end:nop
code ends
end start
           

單步中斷

基本上,CPU在執行完一條指令之後,如果監測到标志寄存器的TF位為1,則産生單步中斷,引發中斷過程。單步中斷的中斷類型碼為1,則它所引發的中斷過程如下。

  1. TF陷阱标志(trap flag):用于調試的單步方式操作;
  2. TF = 1時每條指令執行後産生陷阱,由系統控制計算機;
  3. TF = 0時CPU正常工作。
  4. IF中斷标志(interrupt flag);
  5. IF = 1允許CPU響應可屏蔽中斷請求;
  6. IF = 0關閉中斷。
  • 取得中斷類型碼1;
  • 标志寄存器入棧,TF,IF設定為0;
  • CS,IP入棧;
  • (IP)=(14),(CS)=(14+2)。

如上所述,如果TF=1,則執行好一條指令後,CPU就要轉去執行1号中斷處理程式。

繼續閱讀