一、int指令
int指令的格式为int n
,n为中断类型码,它的功能是引发中断过程。
CPU执行int n
指令,相当于引发一个n号中断的中断过程,执行过程如下:
- 取中断类型码n
- 标志寄存器入栈,IF=0,TF=0
- CS、IP入栈
- (IP)=(n*4), (CS)=(n*4+2)
从此处转去n号中断的中断处理程序。
可以在程序中使用int指令调用任何一个中断的中断处理程序。例如,下面的程序:
assume cs:code
code segment
start: mov ax,0b00h
mov es,ax
mov byte ptr es:[12*160+40*2],'!'
int 0
code ends
end start
这个程序在Windows 2000中的DOS方式下执行时,将在屏幕中间显示一个!
,接下来报除法溢出错误后返回到系统中。
一般情况下,系统将一些具有一定功能的子程序,以中断处理程序的方式提供给应用程序调用。我们在编程的时候,可以用int指令调用这些子程序。当然,我们可以编写一些中断处理程序供别人使用。以后,我们可以将中断处理程序简称为中断例程。
二、编写供应用程序调用的中断例程
通过两个问题来讨论:
问题一:编写、安装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
add dx,dx ;dx:ax存放结果,将结果*2
mov ax,4c00h
int 21h
code ends
end start
分析下,我们要做以下三部分工作:
- 编写实现求平方功能的程序
- 安装程序,将其安装在0:200处
- 设置中断向量表,将程序的入口地址保存在7ch表项中,使其成为中断7ch的中断例程
安装程序如下:
assume cs:code
code segment
start: mov ax,cs
mov ds,ax
mov si,offset spr ;设置ds:si指向源地址
mov ax,0
mov es,ax
mov di,200h ;设置es:di指向目的地址
mov cx,offset sqrend-offset sqr ;设置cx为传输长度
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
问题二:编写、安装7ch的中断例程
功能:将一个全是字母,以0结尾的字符串,转化为大写
参数:ds:si指向字符串的首地址
功能举例:将data段中的字符串转化为大写
assume cs:code
data segment
db 'conservation',0
data ends
code segment
start: mov ax,data
mov ds,ax
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],1101111b
inc si
jmp short change
ok: pop si
pop cx
iret
capitalend: nop
code ends
end start
在中断例程capital用到了寄存器si和cx,编写中断例程和编写子程序的时候具有同样的问题,就是要避免寄存器的冲突。应该注意例程中用到的寄存器值的保存和恢复。