问题:使用7ch中断例程完成loop指令的功能
loop 指令的功能:(1)判断cx值是否为0
(2)不是则跳转到标号s处
应用举例:在屏幕中间显示80个‘ !’
assume codesg
codesg segment
start: mov ax,0b800h
mov es,ax
mov di,160*12
mov bx,offset s - offset se ;注意这里使用标号s的偏移地址减去标号se的偏移地址
mov cx,80
s: mov byte ptr es,[di],'!'
add di,2
mov ax,4c00h
int 7ch
se:nop
mov ax,4c00h
int 21h
codesg ends
end start
;7ch中断例程如下
lp: push bp
mov bp,sp
dec cx
jcxz lpret
add [bp+2],bx
lpret: pop bp
iret
解释:
(1)进入中断例程时 先要pushf 再 push CS 然后 push IP,由此可知栈中数据的存放顺序
(2)中断例程执行完成 使用iret指令还原 标志寄存器 CS IP 即 pop IP / pop CS / popf
(3) int 7ch引发中断过程后,进入中断例程,在中断过程中,当前的标志寄存器、CS和IP都要压栈,此时压入的CS和IP中的内容,分别是调用程序的段地址(可以认为是标号s的段地址)和int 7ch后一条指令的偏移地址(即标号se的偏移地址)
可见,在中断例程中,可以从栈中取得标号s的段地址和标号se的偏移地址,而用标号se的偏移地址加上bx中存放的转移位移(这里bx中的值为负数)就可以得到标号s的偏移地址
(4) 可以利用iret指令,设置CS:IP 就是说 只要将栈中的CS和IP值修改为标号s处的CS和IP 然后再用iret指令 就可以将CS:IP指向标号s的地址
(5)根据 先要pushf 再 push CS 然后 push IP 可得 栈中存放的数据的顺序为 栈顶处为IP 下面是CS 再下面是 flag值
(6)mov bp,sp 得到栈顶位置,add [bp+2],bx 将占中的IP加上转移位移 即标号s处的偏移位移 注意 没有显示说明段寄存器是 bp对应的默认寄存器为ss
(7) iret 指令 等价于 pop IP / pop CS / popf 就是说 iret指令 同时设置了CS IP flag的值