匯編13:int指令


int指令

int指令也可以引發內中斷。

int指令的格式是:

int n

其中n為中斷類型碼。

相當於執行以下步驟:

1、取到中斷類型碼n

2、標志寄存器入棧,IF=0,TF=0

3、CS、IP入棧

4、根據中斷向量表修改CS和IP:(IP)=(n*4),(CS)=(n*4+2)

可見int指令的最終功能就是執行一段中斷處理程序。

案例:以中斷程序的方式實現計算式

需求:求一word型數據的平方,求2*(3456的平方),dx、ax中存放結果的高16位和低16位。

首先准備安裝程序:

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
		
sqrend:	nop

code ends
end start

然后產生對應中斷完成功能:

assume cs:code
code segment
start:	mov ax,3456
	int 7ch									調用中斷處理程序,完成平方
	add ax,ax								低16位相加
	adc dx,dx								高16位相加
	mov ax,4c00h
	int 21h
code ends
end start

案例:以中斷程序的方式完成loop指令循環

需求:在屏幕中間顯示80個“!”

程序:

assume cs:code
code segment
start:	mov ax,0b800h
	mov es,ax
	mov di,160*12
		
	mov bx,offset s-offset se				        計算從se到e的轉移位移
	mov cx,80							設置循環次數
s:	mov byte ptr es:[di],'!'				        在屏幕上顯示符號
	add di,2
	int 7ch								用這條指令代替loop s
se:	nop
	mov ax,4c00h
	int 21h
code ends
end start

要想用int 7ch代替loop s,必須使其完成兩項內容:cx的自減以及將執行跳轉到s標號處。

要跳轉到s標號處,必須設置cs和ip。當中斷發生時,此時會把當時的cs和ip壓入棧中,中斷完成后取出恢復。我們要想辦法讓棧中取出的值對應的cs和ip就是標號s處。這里的cs是不用改變的,因為跳轉發生在同一個段中,關鍵是ip要發生改變。

中斷程序:

lp:	push bp
	mov bp,sp
	dec cx
	jcxz lpret
	add [bp+2],bx
lpret:	pop bp
	iret

下面我們重點研究這段代碼,當中斷發生時,int 7ch這句代碼的cs和ip會入棧,然后把bp寄存器壓入棧中,將sp寄存器賦值給bp(ss:sp時刻指向棧頂,sp相當於偏移地址),然后自減cx,如果cx不為0則繼續執行:

[bp+2],bx

當bp寄存器在中括號中,默認的段地址在ss中,也就是說這條語句實際上是一條改變棧的語句,因為bp此時就等於sp,所以這條語句實際上改變的是棧頂往下第二個元素,也就是剛剛中斷時壓入棧中的ip,這個值加上bx就相當於再次指向標號s(bx是轉移位移),然后bp彈棧,結束中斷。如果cx為0,那么就直接跳到lpret執行,棧中的數據不改變,cs和ip的值也不變,相當於loop結束。

為什么一定要把bp放入棧中再取出呢?因為bp是一個中間寄存器,它的值在調用中斷程序前后不能發生變化。

為什么沒有關於標志寄存器的操作?因為它是第一個被放入棧中的,也就是棧底數據,和本例無關。

由此可見,根據中斷時cs和ip入棧的性質,我們也可以手動調整棧來完成跳轉。

BIOS和DOS提供的中斷機制

在系統板的ROM中存放着一套程序,稱為BIOS(基本輸入輸出系統),BIOS中主要包含以下幾部分內容:

1、硬件系統的檢測和初始化程序

2、外部中斷和內部中斷的中斷例程

3、用於對硬件設備進行的IO操作的中斷例程

4、其他和硬件系統相關的中斷例程

操作系統DOS也提供了很多中斷例程,從操作系統的角度來看,DOS的中斷機制就是操作系統向程序員提供的編程資源。

程序員在編程的時候可以用int指令直接調用BIOS和DOS提供的中斷例程來完成對應的功能。

它們的執行過程如下:

1、開機后CPU初始化CS=0FFFFH,IP=0,開始執行程序,這個位置有一個跳轉指令,CPU轉去執行BIOS中的硬件系統檢測和初始化程序。

2、初始化程序將BIOS提供的中斷程序的入口地址登記在中斷向量表中。

3、硬件系統檢測和初始化完成后,調用int 19h進行操作系統的引導,將計算機交給操作系統來控制。

4、DOS啟動后,將其中斷程序裝入內存並更新中斷向量表。

BIOS中斷例程應用

int 10h是BIOS提供的一個中斷例程,其中包含了多個和屏幕輸出相關的子程序。

設置光標位置功能:

mov ah,2							調用中斷程序的2號子程序,設置光標位置
mov bh,0							位置在第0頁,一般就是屏幕中
mov dh,5							行號為5
mov dl,12							列號為12
int 10h								

在光標位置顯示字符:

mov ah,9							調用中斷程序的9號子程序,在光標位置顯示字符
mov al,'a'							字符為a
mov bl,7							顏色屬性為7
mov bh,0							位置在第0頁
mov cx,3							字符重復個數為3
int 10h

DOS中斷例程應用

int21h是DOS提供的中斷例程。

我們在前面一直在利用int 21h中斷例程的4ch號功能完成程序返回功能:

mov ah,4ch							程序返回
mov al,0							返回值為0
int 21h

簡寫為:

mov ax,4c00h
int 21h

該中斷例程也可以在光標位置顯示字符串:

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					調用9號子程序,顯示字符串
		int 21h
			
		mov ax,4c00h
		int 21h
code ends
end start


免責聲明!

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



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