第十三章
int指令引發的中斷是另一種內中斷
13.1 int指令
格式:int n,n爲中斷類型碼
功能:引發中斷過程
執行過程:
1、取中斷類型碼n
2、標誌寄存器入棧,IF=0 TF=0
3、CS、IP入棧
4、(IP)=(n*4)
(CS)=(n*4+2)
從此轉去執行n號中斷的中斷處理程序
assume cs:code
code segment
start: mov ax,0b800h
mov es,ax
mov byte ptr es:[12*160+40*2],'!'
int 0
code ends
end start
執行這段程序,屏幕中間顯示一個!(我們編程所得),然後顯示“Divide overflow”(這是int 0產生的中斷引起的)
int指令的最終功能和call指令相似,都是調用一段程序
系統將一些具有一定功能的子程序以中斷處理程序的方式提供給應用程序,我們可以通過int指令調用它們,也可以自己編寫中斷處理程序
我們將中斷處理程序簡稱爲中斷例程
13.2 編寫供應用程序調用的中斷例程
編寫、安裝中斷7ch的中斷例程
功能:求一word型數據的平方
參數:(ax)=要計算的數據
返回值:dx、ax分別存放高16、低16位
例:求2*3456^2
assume cs:code
code segment
start: mov ax,3456
int 7ch
add ax,ax
adc dx,dx ; 上一條指令可能帶有進位
mov ax,4c00h
int 21h
code ends
end start
assume cs:code
code segment
start: mov ax,cs
mov ds,ax
mov si,offset sqr ; 設置ds:si指向源地址
mov ax,0
mov es,ax
mov di,200h ; 設置es:di指向目的地址
mov cx,offset sqrend-offset sqr
cld ; 傳輸方向爲正
rep movsb
mov ax,0 ; 設置中斷向量表
mov es,ax
mov word ptr es:[7ch*4],200h
mov word ptr es:[7ch*4+2],0
mov ax,4c00h
int 21h
sqr: mul ax
iret ; pop IP pop CS popf
sqrend: nop
code ends
end start
中斷例程與編寫子程序時一樣,要避免寄存器的衝突,要注意例程中用到的寄存器的值的保存和恢復
13.3 對int、iret和棧的深入理解
用7ch中斷例程完成loop指令的功能
loop s指令的執行需要循環次數和到s的位移兩個信息,7ch中斷例程同樣需要這兩個信息,cx放儲循環次數,bx存放位移
在屏幕中間顯示80個‘!’
assume cs:code
code segment
start: mov ax,0b800h
mov es,ax
mov di,160*12
mov bx,offset s-offset se ; 轉移位移
mov cx,80
s: mov byte ptr es:[di],'!'
add di,2
int 7ch
se: nop
mov ax,4c00h
int 21h
code ends
end start
轉到標號應設置(CS)=標號s的段地址,(IP)=標號s的偏移地址
中斷例程如何獲得s的段地址和偏移地址:在中斷過程中CS和IP都要入棧,(CS)即爲s的段地址,(IP)爲se的偏移地址,所以(IP)+(bx)即爲s的偏移地址
如何設置CS:IP:可以利用iret,我們將(IP)+(bx)入棧,取代之前的(IP),用棧中的內容設置CS、IP,從而實現轉移
7ch中斷例程如下
lp: push bp ; 用到了bp,保存原來的值
mov bp,sp ; sp指向棧頂
dec cx
jcxz lpret
add [bp+2],bx ; [bp+2]存放原本IP值(即se的偏移地址)的字單元
lpret: pop bp
iret
7ch中斷例程所能進行的最大轉移位移是多少:FFFFH,s的偏移地址爲0,int 7ch執行完畢後IP指向FFFFH
用7ch完成jmp near ptr s指令的功能,bx向中斷例程傳送轉移位移
do0: push bp
mov bp,sp
add [bp+2],bx
pop bp
iret
13.4 BIOS和DOS所提供的中斷例程
在系統板的ROM中存放着一套程序,稱爲BIOS(基本輸入輸出系統),BIOS中主要包含以下幾部分內容
1、硬件系統的檢測和初始化程序
2、外部中斷和內部中斷的中斷例程
3、用於對硬件設備進行I/O操作的中斷例程
4、其他和硬件系統相關的中斷例程
操作系統DOS也提供了中斷例程
BIOS和DOS所提供的中斷例程中包含了許多子程序,可以用int指令直接調用
和硬件相關的DOS例程中一般都調用了BIOS的中斷例程
13.5 BIOS和DOS中斷例程的安裝過程
開機後CPU加電,初始化(CS)=0FFFFH (IP)=0,自動從FFFF:0單元開始執行程序,FFFF:0處有一條跳轉指令,CPU執行該指令後,轉去執行BIOS中的硬件系統檢測和初始化程序
初始化程序將建立BIOS所支持的中斷向量,即將BIOS提供的中斷例程的入口地址登記在中斷向量表中,注意,對於BIOS所提供的中斷例程只需要在中斷向量表中登記入口即可,因爲它們是固化在ROM中的,一直在內存中存在
硬件系統檢測和初始化完成後,調用int19h進行操作系統的引導,從此將計算機交給操作系統控制
DOS啓動後,除了完成其他工作,還將它所提供的中斷例程裝入內存,並建立相應的中斷向量(操作系統並不存儲在內存中,因此其中斷例程是需要被加載到內存中的)
判斷對錯:
1、我們可以編程改變FFFF:0處的指令,使得CPU不去執行BIOS中的程序
錯,因爲ROM是隻讀的
2、int 19h中斷例程可以由DOS提供
錯,在調用int 19h之前,DOS還沒啓動
13.6 BIOS中斷例程應用
int 10h中斷例程由BIOS提供,其中包含多個和屏幕輸出相關的子程序
一般來說,一個供程序員調用的中斷例程往往包含多個子程序,中斷例程內部用傳遞進來的參數決定執行哪個子程序
BIOS和DOS提供的中斷例程,都用ah來傳遞內部子程序的編號
;int 10h 中斷例程設置光標位置的功能
mov ah,2 ; (ah)=2表示調用10h號例程的2號子程序,功能爲設置光標位置
mov bh,0 ; 提供參數,設置光標到第0頁
mov dh,5 ; 提供行號
mov dl,12 ; 提供列號
int 10h ; 參數設置完畢後,調用中斷例程
bh中頁號的含義:內存中B800H~BFFFFH共32kB空間,爲80*25彩色字符的顯示緩衝區,彩色緩衝區分8頁,顯示器顯示任意一頁的內容,一般顯示第0頁
; 在光標位置顯示字符功能
mov ah,9 ; 例程的9號子程序,在光標位置顯示字符
mov al,'a' ; 字符
mov bl,7 ; 顏色屬性
mov bh,0 ; 第0頁
mov cx,3 ; 字符重複個數
int 10h ; 調用
bl的顏色屬性設置與之前的顯存中的屬性字節的格式相同
編程,在屏幕5行12列顯示3個紅底高亮閃爍綠色的’a’
assume cs:code
code segment
mov ah,2 ; 設置光標位置
mov bh,0
mob dh,5
mov dl,12
int 10h
mov ah,9 ; 在光標位置顯示字符
mov al,'a'
mov bl,11001010b
mov bh,0
mov cx,3
int 10h
mov ax,4c00h
int 21h
code ends
end
13.7 DOS中斷例程應用
int21h是DOS提供的中斷例程,其中包含了DOS提供給程序員在編程時調用的子程序
我們之前一直實驗的是int21h的4ch號功能,即程序返回功能
mov ah,4c ; 程序返回
mov al,0 ; 提供參數,返回值
int 21h
; 我們常寫爲
mov ax,4c00h
int 21h
int21h中斷例程中有顯示字符串的功能
編程,在屏幕的5行12列顯示字符串
assume cs:code
data segment
db 'Welcome to masm','$' ; 字符串要以$爲結尾,但是不顯示
data ends
code segment
start: mov ah,2 ; 置光標
mov bh,0
mov dh,5
mov dl,12
int 10h
mov ax,data
mov ds,ax
mov dx,0 ; 需要由ds:dx指向字符串的首地址
mov ah,9
int 21h
mov ax,4c00h
int 21h
code ends
end start
如果字符串較長,遇到行尾,程序自動轉到下一行開頭繼續顯示,如果到了最後一行,還能自動上卷一行