第13章 int指令
13.1 int指令
int指令的作用是调用任何一个中断的中断处理程序,CPU指令int n,相当于引发一个n号中断处理程序
codesg segment
start:mov ax,0b800h
mov es,ax
mov byte ptr es:[12*160+32*2],'!'
int 0
codesg ends
end start
在这个程序中,不仅会在屏幕中显示!字符,还会输出divide overflow等内容,出现!字符是因为我们将该字符放到显存中,而除法溢出显示则完全是因为我们int 0指令执行0号中断处理程序(中断例程)
int指令为我们直接使用这些中断例程提供了一条途径
13.2 编写供应用程序调用的中断例程
问题1 求一个字型数据的平方,ax做参数,结果高位放在dx,低位在ax,如求2×(3456×3456)的值
调用程序如下:
codesg segment
mov ax,3456
int 7ch ;调用7ch处的中断例程实现3456的平方
add ax,ax ;实现2倍的ax平方
adc dx,dx ;我们用程序运算结果时可能会产生进位,adc指令可以完美处理这个问题
mov 4c00h
int 21h
调用程序如上,我们还需要解决中断例程任何得到3456的平方及将编写的程序复制,最后还需要把入口地址放到中断向量表中,也就是我们上章学的主要内容
codesg segment
mov ax,cs
mov ds,ax
mov ax,0
mov es,ax
mov si,offset sqrend-offset sqr
mov di,200h
cld
rep movsb
mov word ptr es:[7ch*4],200h
mov word ptr es:[7ch*4+2],0
mov 4c00h
int 21h
sqr:mul ax
iret ;iret指令前面讲过,将栈中的值赋给cs,ip和标志寄存器
sqrend:
nop
mov ax,4c00h
int 21h
code ends
end start
问题二 将一个全是字母,以0结尾的字符串转换成大写
调用程序如下:
data segment
db 'conversation',0
code segment
start:mov ax,data
mov ds,ax
mov si,0
int 7ch
mov 4c00h
int 21h
安装程序如下:
code segment
start:mov ax,cs
mov ds,ax
mov ax,0
mov es,ax
mov si,offset capend-offset cap
mov di,0200h
cld
rep movsb
mov word ptr es:[7ch*4],0200h
mov word ptr es:[7ch+2],0
mov ax,4c00h
int 21h
cap: ;注意!此时的ds,si的值应该承接调用程序的
push cx
push si
mov ch,0
mov cl,ds:[si]
jcxz ok
and ds:[si],11011111B
inc si
jmp short cap
ok:pop si ;如果遇到0则转移到ok处,将最开始的cx,si从栈中释放出来
pop cx
iret ;将原来的ip,cs,和标志寄存器放回去
capend:
nop
cap ends
end start
13.3 对int,iret和栈的深入理解
不知道为毛,没看懂可能脑子懵了,过一段时间再看
13.4 BIOS和DOS所提供的中断例程
DOS中有许多中断例程,BIOS同样也提供了许多实用的中断例程,我们都可以用int指令调用,当我们使用DOS中断例程的时候通常都同时调用了BIOS的中断例程!
13.5 BIOS和DOS中断例程的安装过程
在这里给我们说明了计算机中中断例程如何安装到内存中
1.计算机开机CPU通电之后,初始化的cs=0FFFFH,IP=0,此处有一条转跳指令让CPU执行BIOS的硬件系统检测和初始化程序
2.初始化程序会将BIOS中断例程的中断向量登记在中断向量表中,BIOS中断例程固化在ROM中一直存在,是只读的我们无法修改!
3.硬件系统检测和初始化程序之后,调用int 19h进行操作系统的引导,计算机就此由操作系统控制
4.操作系统接管计算机之后,启动DOS,将DOS提供的中断例程装入内存并建立中断向量表
检测点13.2
(1): 错误
因为FFFF:0处的指令是BIOS提供的中断例程是固化在ROM中,为只读数据我们无法修改
(2): 错误
int 19h中断例程执行,此后计算机才开始由计算机掌管,然后DOS开始启动,在此之前DOS提供的中断例程我们不能使用
13.6 BIOS中断例程的应用
一个中断例程往往有多个子程序,当执行某个中断例程时我们可以用ah的值来决定执行哪个子程序
用10h处中断例程在第0页的5行12列置光标程序如下:
mov ah,2 ;表示执行2号子程序,其作用是置光标
mov bh,2 ;第0页
mov dh,5 ;5行
mov dl,12 ;12列
int 10h ;执行10h处中断例程
显示字符程序如下:
mov ah,9 ;显示字符
mov al,'a' ;显示字符a
mov bl,7 ;颜色属性
mov bh,0 ;0页
mov cx,3 ;显示3次
int 10h
13.7 DOS中断例程应用
DOS中断例程中我们最熟悉的便是
mov ax,4c00h
int 21h
原本应为:
mov ah,4c ;程序返回
mov al,0 ;返回值
int 21h
同样的,DOS中断例程也可以和上面BIOS中断例程一样有置光标等功能,方法同
实验13 编写,应用中断例程
(1)编写安装int 7ch中断例程,显示一个0结束的字符串…
assume cs:codesg
codesg segment
start:mov ax,cs
mov ds,ax
mov ax,0
mov es,ax
mov di,0200h
mov si,offset cap
mov cx,offset capend-offset cap
cld
rep movsb ;以上部分是将中断例程安装到内存中
mov word ptr es:[7ch*4],0200h ;这两句在将入口地址放到中断向量表中
mov word ptr es:[7ch*4+2],0
mov ax,4c00h
int 21h
cap:push si ;开始中断例程之前,把原本各个寄存器值放入栈中
push di
push cx
mov ax,08b00h
mov es,ax
mov al,160 ;这部分是利用dh和dl计算出字符串在显存中出现的位置,并将最终具体地址放在di中
mul dh
mov di,ax
mov al,2
mul dl
add di,ax
mov es:[di+1],cl ;放颜色属性
s:mov ch,0
mov cl,ds:[si]
jcxz ok ;前面三句,判断是否读到0,读到0就跳到标号ok处结束
mov es:[di],cl
inc si
add di,2
loop s
capend:nop
ok:pop cx
pop di
pop si
iret ;将各个寄存器和原来cs,ip的值返回
mov ax,4c00h
int 21h
codesg ends
end start