程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> 匯編語言 >> 匯編基礎:中斷

匯編基礎:中斷

編輯:匯編語言

中斷是計算機輸入輸出程序設計常用的控制方式,有一點計算機操作系統基礎的人對這個詞一定不會陌生,中斷控制技術主要應用在以下幾個方面:

1、及時處理計算機中突發故障,比如說突然斷電、執行指令時溢出內存故障等等,

2、協調主機與外設工作速度的矛盾

3、在實時控制系統中,及時處理各控制點的現場

一、中斷源及中斷類型碼

引起中斷的原因叫做中斷源,8086/8088 CPU最多可以處理256種類型的中斷,這些中斷可來自CPU內部的原因,也可來自外設的I/O請求,根據中斷源可將中斷分為外部中斷和內部中斷兩大類。

1、外部中斷

外部中斷是由I/O設備或其他異常情況引起的,這類中斷的出現通常是隨機的,外部中斷又稱為硬件中斷,外部中斷又可分為不可屏蔽中斷和可屏蔽中斷,一般由外設引起的中斷為可屏蔽中斷,在標志寄存器中,當IF=1時可屏蔽中斷和不可屏蔽中斷都能被CPU響應,若IF=0時,不可屏蔽中斷能被CPU響應,但屏蔽中斷不能夠呗CPU響應。中斷允許標志位IF的狀態可使用STL(使IF=1)和CLI(使IF=0)設置為開中斷和關中斷。

2、內部中斷

由CPU內部引起的中斷稱為內部中斷,比如說除法運算出錯、執行軟中斷指令、單步中斷等,它們都是非屏蔽中斷,內部中斷一般又分為下面四種:

【a】、除法出錯中斷:當除數為0或處除法中所得商過大時,立即產生一個內部中斷。

【b】溢出中斷指令INTO:這是一條軟件中斷指令,當執行該指令時,若前面的運算已產生溢出,是OF=1時,便產生一個內部中斷,若OF=0,邊不會產生中斷。

【c】、軟中斷指令INT  n:這是系統提供兩組功能子程序,一組是ROM的BIOS中,另一組在OS中,這兩組功能子程序實現常用的輸入輸出及文件處理等基本操作,使用軟中斷指令INT,調用這些功能子程序,以內部中斷形式執行這些基本操作。

【d】、單步中斷:當標志寄存器中單步標志位TF=1,CPU便進入單步工作方式,即每執行一條指令,就自動產生內部中斷,停止執行程序,一共用戶檢查程序執行結果。

二、中斷優先級

當同一時刻有若干個不同的中斷請求出現時,CPU會先執行那一個中斷呢?這就涉及到了中斷的優先級問題,這就如同我們所學的高級語言中的符號運算的優先級一樣,而對於中斷的優先級如下:

高------------------------------------------------------>低

內中斷(除法出錯、INT n、INTO)、不可屏蔽中斷、可屏蔽中斷、單步中斷

三、中斷過程

中斷的過程類似於我們之前所說的子程序調用過程,不同的是在保護中斷現場時,除了保存返回地址CS和IP外,還要保存標志寄存器FLAGS的內容,另外當中斷響應後CPU自動將IF和TF標志清0,其目的是在CPU進入處理程序後不再響應其他別的中斷請求,如果我們還想在執行某一個中斷的過程中還可以去執行另外的中斷,我們可以通過STI指令將IF標志位置1

一個完整的中斷過程有下面5個步驟:1、中斷請求2、中斷優先級判定3、中斷響應4、中斷處理5、中斷返回。

四、編寫自己的中斷處理程序

中斷處理程序大部分由BIOS或DOS系統提供的,當我們編寫自己需要的中斷處理程序時,應該注意下面幾個問題:

1、程序中不用數據段,一般將數據變量直接放入代碼段中

2、程序中不用堆棧段,中斷處理程序借用調用者的堆棧段

3、在進入中斷處理程序後,首先要保護現場。在程序中用到的寄存器需要壓入堆棧保護起來,在程序結束前恢復各寄存器內容,使用時要注意堆棧後進先出的原則

4、在中斷處理程序中,若允許中斷嵌套,應保護現場後,用STI指令開中斷,在中斷處理程序的工作結束後,在恢復現場返回之前用CLI指令關中斷。

下面我們以一個簡單的例子來說明問題

例:編寫一個中斷處理程序,中斷類型號為60H,功能為顯示一個字符串“Yzs”

CODE    SEGMENT    
ASSUME  CS:CODE, DS:CODE    
MAIN    PROC    FAR    
START:  MOV AL, 60H         ;獲取原60H中斷向量    
    MOV AH, 35H    
    INT 21H             
    PUSH    ES          ;讀取的中斷向量位於ES:BX中    
    PUSH    BX          ;壓入堆棧保存    
    MOV AX, SEG INT_PROGRAM ;設置新的60H中斷向量    
    MOV DS, AX          ;中斷向量的段地址放在DS中    
    MOV DX, OFFSET  INT_PROGRAM ;中斷向量的地址放在DX中    
    MOV AL, 60H    
    MOV AH, 25H         ;用INT  21H的25H號功能設置中斷向量    
    INT 21H    
    INT 60H         ;用新的60H中斷向量    
    POP DX          ;把原中斷向量彈出堆棧    
    POP DS    
    MOV AL, 60H    
    MOV AH, 25H         ;恢復原中斷向量    
    INT 21H    
    MOV AX, 4C00H       ;返回DOS    
    INT 21H    
MAIN    ENDP    
DISP    DB  'Yzs'           ;待顯示的字符串    
        
INT_PROGRAM PROC    FAR     ;新60H中斷處理程序    
    PUSH    AX          ;保護現場    
    PUSH    BX    
    PUSH    CX    
    PUSH    DX    
    PUSH    SI    
    PUSH    DI    
    PUSH    BP    
    PUSH    DS    
    PUSH    ES    
    STI         ;開中斷    
    PUSH    CS      ;設置DS=CS    
    POP DS    
    MOV DX, OFFSET  DISP    
    MOV AH, 09H    
    INT 21H     ;顯示字符    
    CLI         ;關中斷    
    POP ES      ;恢復現場    
    POP DS    
    POP BP    
    POP DI    
    POP SI    
    POP DX    
    POP CX    
    POP BX    
    POP AX    
    IRET    
INT_PROGRAM ENDP    
CODE    ENDS    
    END START

五、BIOS和DOS中斷調用

我們所說的BIOS就是基本輸入輸出系統,它存放在內存地址較高地址區域的ROM中,它不僅處理系統的全部中斷,還提供對主要I/O接口的控制功能,每個功能的控制模塊的入口地址都在中斷矢量表中,在1K的中斷矢量表中,共有256個中斷調用入口地址,對這些中斷調用是通過軟中斷INT來實現的,軟中斷指令的操作數就是中斷類型碼。DOS是磁盤操作系統,是由BIOS開機後自動裝入內存中的,DOS中斷是建立在BIOS之上的中斷,它借用了BIOS的軟中斷功能來調用系統的中斷服務程序。

在BIOS中斷類型中,0H--9H號中斷為硬中斷,一般不用程序調用,是由I/O接口觸發的。其他中斷則是由用戶通過指令來控制的。在DOS中斷調用中,主要使用21H中斷,因為該中斷中包括了常用的鍵盤、磁盤、打印機等一系列I/O接口,在調用時只需將AH寄存器設置成所需要的功能號並設置一些其他所對應的參數即可完成調用功能。因為在平常的編程中一般用得較多的是對硬件依賴不大且代碼量比較少的DOS中斷調用,所以下面我就側重介紹下有關DOS中斷調用的實例。

1、鍵盤DOS功能調用

有關鍵盤方面的INT  21H有1、6、7、8號功能

【a】、1號功能

功能:從鍵盤讀入一個字符,將字符回顯在屏幕上,同時將輸入的字符送入到AL寄存器中,如果讀到的字符是Ctrl+Break鍵,則結束程序執行

【b】、6號功能

功能:直接讀寫控制台

輸入參數:AH=06H,若DL==00FH表示輸入鍵盤字符, 若DL=0--0FFH,表示輸出字符

返回結果:輸入時,ZF=0,表示有字符輸入,AL為輸入字符的ASCII碼

ZF=1,表示無字符輸入,AL=0

輸出時,無返回結果。

【c】、7號功能

功能:從鍵盤讀入一個字符,不回顯在屏幕上,同時將輸入字符送入到AL寄存器中,也不檢測是否為Ctrl+Break鍵。

【d】、8號功能

功能:1號功能基本相同,只是字符不回顯在屏幕上。

2、顯示器DOS功能調用

DOS中的INT  21H提供的顯示功能主要有以下三個:

【a】、當AH=02H時,功能是顯示一個字符,光標跟隨字符移動,檢測Ctrl+Break鍵。

輸入參數:DL為待顯示字符的ASCII碼

返回結果:無

【b】、當AH=06H時,功能是顯示一個字符,光標跟隨字符移動,但不檢測Ctrl+Break鍵。

輸入參數:DL為待顯示字符的ASCII

返回結果:無

【c】、當AH=09H時,功能是顯示字符串,光標跟隨字符串移動

輸入參數:DS:DX為待顯示字符串的首地址,字符串必須以“$”結尾

返回結果:無

我在我的另一篇博文中介紹過過於字符串的輸出這部分,是我這個匯編專題的第一篇,有興趣的朋友可以看下http://yiluohuanghun.blog.51cto.com/3407300/935340

我們再以一個例子結束我們這節關於中斷的知識:

例:編程產生10個0--51之間的隨機整數,放入內存BUF開始的各單元中。

DATA    SEGMENT    
    BUF DB  10  DUP  (?)    
DATA    ENDS    
CODE    SEGMENT    
ASSUME  CS:CODE, DS:DATA    
START:  MOV AX, DATA    
    MOV DS, AX    
            
    LEA BX, BUF    
    MOV CX, 10    
    STI    
NEXT:   PUSH    CX    
    MOV AH, 0    
    INT 1AH    
    MOV AL, DL    
    CBW    
    DIV 5    
    MOV [BX], AL    
    INC BX    
    POP CX    
    LOOP    NEXT    
    MOV 4CH    
    INT 21H    
CODE    ENDS    
    END START

到此為止,關於中斷部分我也大致給大家說完了,當然了,我在這裡寫的只是這方面的一點點東西,起個拋磚引玉的作用,希望能夠對大家有幫助。

本文出自 “驿落黃昏” 博客,請務必保留此出處http://yiluohuanghun.blog.51cto.com/3407300/941589

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved