汇编语言编写供应用程序调用的中断例程

问题一:编写、安装中断7ch的中断例程。
功能:求一word型数措的平方
参数:(ax)=要计算的数据。
返回值:dx, ax中存放结果的高16位和低16位。
应用举例:求2*3456^20

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

分析一下,我们要做以下3部分工作。
(1)编写实现求平方功能的程序;
(2)安装程序,将其安装在0:200处;
(3)设置中断向量表,将程序的入口地址保存在7ch表项中,使其成为中断7ch的中断例程。
安装程序如下

assume cs:code
code segment
start:        mov ax , cs
        mov ds , ax
        mov si , offset sqr
        mov ax , 0
        mov es , ax
        mov di , 200h
        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

注意,在中断例程sqr的最后,要使用iret指令。用汇编语法描述,fret指令的功能为

pop IP
pop CS
popf

CPU执行int 7ch指令进入中断例程之前,标志寄存器、当前的CS和IP被压入栈中,在执行完中断例程后,应该用fret指令恢复int 7ch执行前的标志寄存器和Cs, IP的值,从而接着执行应用程序。 int指令和fret指令的配合使用与call指令和ret指令的配合使用具有相似的思路。
问题二:编写、安装中断7ch的中断例程。

功能:将一个全是字母,以0结尾的字符串,转化为大写
参数:dsai指向字符串的首地址。
应用举例:将data段中的字符串转化为大写。

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

        int 7ch

        mov ax , 4c00h   ; 如果中断程序中有这段程序这里就可以不加,如果中断程序中是iret,这里就要加上;
        int 21h          ; 不然无法返回dos输入命令,这里和中断程序都加上这段也可以


capital:        jmp short change
        db 'conversation' , 0
change:        mov ax , cs
        mov ds , ax
        mov si , 202h
        mov ax , 0b800h
        mov es , ax
        mov di , 7c6h      ; 具体在显示缓冲区的显示位置偏移
s:        mov cl , [si]
        mov ch , 0
        jcxz return
        and byte ptr [si] , 11011111b
        mov cl , [si]
        mov es:[di] , cl
        mov byte ptr es:[di+1] , 2
        inc si
        add di , 2
        jmp short s

return:        iret       ;这里要写上中断返回或者 mov ax , 4c00h  int 21h  返回dos,不然执行后程序无法输入,因为执行完中断CS:IP接着向下去执行了;
capitalend:    nop

code ends
end start

在中断例程。apital中用到了寄存器si和cx,编写中断例程和编写子程序的时候具有同样的问题,就是要避免寄存器的冲突。应该注意例程中用到的寄存器的值的保存和恢复。


发布日期:

所属分类: 编程 标签:  


没有相关文章!