一、分析程序,在运行前思考:这个程序是否能够正确返回?
运行之后再思考:为什么是这种结果?
通过这个程序加深对相关内容的理解。
1 assume cs:codesg 2 codesg segment 3 4 mov ax,4c00h 5 int 21h 6 7 start: mov ax,0 8 s: nop 9 nop 10 11 mov di,offset s 12 mov si,offset s2 13 mov ax,cs:[si] 14 mov cs:[di],ax 15 16 s0: jmp short s 17 18 s1: mov ax,0 19 int 21h 20 mov ax,0 21 22 s2: jmp short s1 23 nop 24 25 codesg ends 26 end start
二、上机调试
1.调试程序之前,debug 程序,然后-r查看寄存器状态
2.-u 指令查看反汇编格式的代码,需要注意的是我要从Ip为0的地方开始查看代码(需要指定开始和结束的位置
才能看到所有的反汇编代码)
mov di,offset s,s的偏移地址是8
mov si,offset s2,s2的偏移地址20
jmp short s1,s1的偏移地址18
3.开始一步一步调试
执行了上面的5条指令后,查看代码段中的数据
4.执行mov ax,cs:[si]后,将代码段偏移地址为20的字单元数据赋值给寄存器ax
5.执行完mov cs:[di]后,查看代码段的数据,偏移地址为8的字单元被修改成F6BE
6.此时,-u命令查看代码段中的代码,执行完JMP 0008,就会跳转到红色框处
7.继续执行JMP 0000,程序会执行到代码段的最开始位置,解释:其中这里机器语言EBF6中的F6很重要,就是
程序要跳转的标号,F6的补码是-0A,即相对于本指令的下一条指令的开始向上偏移10个字节,也就是
代码段的开始位置,如下图所示,程序就可正常返回了。
关于补码的知识,可以参考本人博客:https://www.cnblogs.com/TonyJia/p/12581831.html
总结:运用王爽老师在P180页的话,CPU在执行jmp指令的时候并不需要转移的目的地址,
而包含的是转移的位移。这个位移,是编译器根据汇编指令中的“标号”计算出来的。
本博参考了他的文章: