问题:用7ch中断例程完成loop指令的功能。
应用举例:在屏幕中间显示80个‘!’。
为了模拟loop指令,7ch中断例程应具备下面的功能:
(1)dec cx (2) 如果cx不等于0,转到标号s处执行,否则向下执行。
那么中断例程如何得到标号s的段地址和偏移地址? 请看下面一段代码:
mov ax,0b800h
mov es,ax
mov di,160*12
mov bx,offset s-offset se //设置从标号se到s的转移位移
mov cx,80
s: mov byte ptr es:[di],'!'
add di,2
int 7ch
se: nop
mov ax,4c00h
int 21h
7ch中断例程:
lp: push bp
mov bp,sp
dec cx
jcxz lpret
add ss:[bp+2],bx
lpret: pop bp
iret
lpend: nop
bx寄存器的指修改了((ss)*16+(bp)+2)处为se的偏移地址,最后用iret出栈返回,cs:ip即从标号s处开始执行指令。
完整代码如下
assume cs:code
code segment
start:
;安装中断例程
mov ax,cs
mov ds,ax
mov si,offset lp
mov ax, 0
mov es,ax
mov di,200h
mov cx,offset lpend - offset lp
cld
rep movsb
;设置中断向量
mov word ptr es:[7ch * 4 ],200h
mov word ptr es:[7ch * 4 + 2 ], 0
;中断例程应用举例
mov ax,0b800h
mov es,ax
mov di, 160 * 12
mov bx,offset s - offset se
mov cx, 80
s: mov byte ptr es:[di], ' ! '
add di, 2
int 7ch ;调用中断例程
se: nop
mov ax,4c00h
int 21h
;中断例程
lp: push bp
mov bp,sp
dec cx
jcxz lpret
add ss:[bp + 2 ],bx
lpret: pop bp
iret
lpend: nop
code ends
end start
code segment
start:
;安装中断例程
mov ax,cs
mov ds,ax
mov si,offset lp
mov ax, 0
mov es,ax
mov di,200h
mov cx,offset lpend - offset lp
cld
rep movsb
;设置中断向量
mov word ptr es:[7ch * 4 ],200h
mov word ptr es:[7ch * 4 + 2 ], 0
;中断例程应用举例
mov ax,0b800h
mov es,ax
mov di, 160 * 12
mov bx,offset s - offset se
mov cx, 80
s: mov byte ptr es:[di], ' ! '
add di, 2
int 7ch ;调用中断例程
se: nop
mov ax,4c00h
int 21h
;中断例程
lp: push bp
mov bp,sp
dec cx
jcxz lpret
add ss:[bp + 2 ],bx
lpret: pop bp
iret
lpend: nop
code ends
end start