汇编语⾔--int指令
int指令
中断信息可以来⾃CPU的内部和外部,当CPU的内部有需要处理的事情发⽣的时候,将产⽣需要马上处理的中断信息,引发中断过程。
上⼀章讲解了0号中断和单步中断,这⼀章将讲解另⼀种重要的内中断,由int指令引发的中断。
int指令
格式:int n
n为中断类型码,它的功能是引发中断过程。
CPU执⾏int n指令,相当于引发⼀个n号中断的中断过程,执⾏过程如下:
1)取中断类型码n;
2)标志寄存器⼊栈,IF=0,TF=0;
3)CS、IP⼊栈
4)(IP)=(n*4),(CS)=(n*4+2)
从此处转去执⾏n号中断的中断处理程序。
可以在程序中使⽤int指令调⽤任何⼀个中断的中断处理程序。
assume cs:code
code segment
start:    mov ax,0b800h
move s,ax
mov byte ptr es:[12*160 +40*2],’!’
int 0
code ends
end start
这个程序在Windows2000中的DOS⽅式下执⾏时,将在屏幕中间显⽰⼀个“!”,然后显⽰“Divide overflow”后返回到系统中。“!”是我们编程显⽰的,⽽“Divide overflow”是哪⾥来的呢?我们的程序中⼜没有做除法,不可能产⽣除法溢出。
程序是没有做除法,但是在结尾使⽤了int 0指令。
CPU执⾏int 0指令时,将引发中断过程,执⾏0号中断处理程序,⽽系统设置的0号中断处理程序的功能是显⽰“Divide overflow”,然后返回系统。
int指令的最终功能和call指令相似,都是调⽤⼀段程序。
⼀般情况下,系统将⼀些具有⼀定功能的⼦程序,以中断处理程序的⽅式提供给应⽤程序调⽤。我们在编程的时候,可以⽤int指令调⽤这些⼦程序。当然,也可以⾃⼰编写⼀些中断处理程序供别⼈使⽤。
中断处理程序可简称为中断例程。
编写供应⽤程序调⽤的中断例程
前⾯已经编写过中断0的中断例程了,现在我们讨论可以供应⽤程序调⽤的中断例程的编写⽅法。1,⽰例⼀
编写、安装中断7ch的中断全程,功能:求⼀word型数据的平⽅。
参数:(ax)=要计算的数据。
返回值:dx、ax中存放结果的⾼16位和低16位。
应⽤举例:求2*3456^2
assume cs:code
code segment
start:    mov ax,3456                ;(ax)=3456
int 7ch                        ;调⽤中断7ch的中断例程,计算ax中的数据的平⽅
add ax,ax
adc dx,dx                            ;dx:ax存放结果,将结果乘以2
mov ax,4c00h
int 21h
code ends
end start
分析,我们要做三部分⼯作:
1)编写实现求平⽅功能的程序;
2)安装程序,我们将其安装在0:200处;
3)设置中断向量表,将程序的⼊⼝地址保存在7ch表项中,使其成为中断7ch的中断例程。
安装程序如下:
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              ;设置cx为传输长度
cld                              ;设置传输⽅向为正
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
注意,在中断例程sqr的最后,要使⽤iret指令。⽤汇编语法描述,iret指令的功能为:
pop IP
pop CS
popf
CPU执⾏int 7ch指令进⼊中断例程之前,标志寄存器、当前的CS和IP被压⼊栈中,在执⾏完中断例程后,应该⽤iret指令恢复int 7ch执⾏前的标志寄存器和CS、IP的值,从⽽接着执⾏应⽤程序。
int指令和iret指令的配合使⽤与call指令和ret指令的配合使⽤具有相似的思路。
2,⽰例⼆
编写、安装中断7ch的中断例程,功能:将⼀个全是字母,以0结尾的字符串,转化为⼤写。
参数:ds:si指向字符串的⾸地址。
应⽤举例:将data段中的字符串转化为⼤写。
assume cs:code
data segment
db ‘conversation’,0
data ends
code segment
start:    mov ax,data
mov si,0
int 7ch
mov ax,4c00h
int 21h
code ends
end start
安装程序如下:
assume cs:code
汇编语言结束指令code segment
start:    mov ax,cs
mov ds,ax
mov si,offset capital
mov ax,0
mov es,ax
mov di,200h
mov cx,offset capitalend – offset capital              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
capital: push cx
push si
change:  mov cl,[si]
mov ch,0
jcxz ok
and byte ptr [si],11011111b
inc si
jmp short change
ok:  pop si
pop cx
iret
capitalend:    nop
code ends
end start
在中断例程capital中⽤到了寄存器si和cx,编写中断例程和编写⼦程序的时候具有同样的问题,就是要避免寄存器的冲突。应该注意例程中⽤到的寄存器的值的保存和恢复。
对int、iret和栈的深⼊理解
问题:⽤7ch中断例程完成loop指令的功能。
loop s的执⾏需要两个信息,循环次数和到s的位移,所以7ch中断例程要完成loop指令的功能,也需要这两个信息作为参数。我们⽤cx存放循环次数,⽤bx存放位移。
BIOS和DOS所提供的中断例程
在系统板的ROM中存放着⼀套程序,称为BIOS(基本输⼊输出系统),BIOS中主要包含以下⼏部分内容:
1)硬件系统的检测和初始化程序;
2)外部中断和内部中断的中断例程;
3)⽤于对硬件设备进⾏了I/O操作的中断例程;
4)其他和硬件系统相关的中断例程。
操作系统DOS也提供了中断例程,从操作系统的⾓度来看,DOS的中断例程就是操作系统向程序员提供的编程资源。
BIOS和DOS在所提供的中断例程中包含了许多⼦程序,这些⼦程序实现了程序员在编程的时候经常需要⽤到的功能。程序员在编程的时候,可以⽤int指令直接调⽤BIOS和DOS提供的中断例程,来完成某些⼯作。
和硬件设备相关的DOS中断例程中,⼀般都调⽤了BIOS中的中断例程。
BIOS和DOS中断例程的安装过程
前⾯我们都是⾃⼰编写中断例程,将它们放到安装程序中,然后运⾏安装程序,将它们安装到指定的内存区中。此后,别的应⽤程序才可以调⽤。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。