思路:
assume cs:code
code segment
start: 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
code ends
end start
在7ch中断处理程序中,需要返回到s处来完成循环
在跳转到7ch时,cs和ip入栈,ip存放的正是se的偏移量
bx=s-se,现在我们得到了se的偏移量,只需要加上bx就能得到
s的偏移量了
因此在处理程序中,我们使用下面这段代码:
show: push bp
mov bp, sp
dec cx
jcxz showret
add [bp+2], bx
showret: pop bp
iret
分析一下这段代码,访问栈段内存,所以要使用bp寄存器
先保存他的值,然后让他指向栈顶,现在的栈中存储的数据是这样的:
+----+ 每次将cx的值减1,当cx值为0时,恢复bp的值并返回
| bp | 如果cx的值不为0,就修改ip的值,将其加上bx,得到标号s的
+----+ 偏移地址,然后恢复bp的值,执行iret指令,相当于
| ip | pop ip pop cs
+----+ 这样一来,程序就会执行到s标号处
| cs | 如果add [bp+2], bx没有被执行,当iret执行完之后
+----+ 就会执行到se处,这时程序也就结束了
|flag|
+----+ 完整的安装程序:
|····| assume cs:code
+----+
code segment
start: mov ax, cs
mov ds, ax
mov si, offset show
mov ax, 0
mov es, ax
mov di, 200h
mov cx, offset showend-offset show
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
show: push bp
mov bp, sp
dec cx
jcxz showret
add [bp+2], bx
showret:pop bp
iret
showend:nop
code ends
end start
t2.asm:
assume cs:code
code segment
start: 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], '!'
mov byte ptr es:[di+1], 02h
add di, 2
int 7ch
se: nop
mov ax, 4c00h;
int 21h
code ends
end start
t1.asm(安装程序)
assume cs:code
code segment
start: mov ax, cs
mov ds, ax
mov si, offset show
mov ax, 0
mov es, ax
mov di, 200h
mov cx, offset showend-offset show
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
show: push bp
mov bp, sp
dec cx
jcxz showret
add [bp+2], bx
showret:pop bp
iret
showend:nop
code ends
end start
运行过程:
先运行t1.exe,安装中断程序
再通过debug调试t2.exe
运行至int 7ch处时如下所示:
![](https://img-blog.csdnimg.cn/img_convert/bfdcaaa6cf7a9ed8d9d52b95941c2077.png)
可以看出此时的CS 、IP、和栈中的内容,栈中的数值为之前单步中断保存的flag、CS、IP等寄存器的值,再执行一步-t,进入中断服务函数,如下所示
![](https://img-blog.csdnimg.cn/img_convert/bfd66cf0e9e4f6ea15ff723d24e61541.png)
此时栈顶指针为FFFA(指向1C),其中076A为保存的CS,001C为保存的IP值,继续执行两次-t,看到:
![](https://img-blog.csdnimg.cn/img_convert/6ebff6457300f9a8b486b0b081252afd.png)
SP变为FFF8指向(00),BP的值0000入栈后,将SP的值赋值给了BP。继续多次执行-t后如图:
![](https://img-blog.csdnimg.cn/img_convert/963b4ce4e1a40cf7ace9a336bf27a52a.png)
栈中保存的IP值已经被重新赋值为000E(001c+FFF2),继续执行如下:
![](https://img-blog.csdnimg.cn/img_convert/7c92989f77f6a8de4d7120020c0f9036.png)
将栈中的BP、IP、CS、flag寄存器依次出栈,栈顶指针SP变为0000.程序将会跳到S处继续运行,
至此,完成了第一次循环。后面的循环调用过程类似