实验8
首先得配置DOS环境和Debug工具。
在Vscode插件中搜索MASM/TASM下载。(已配置好环境)
实验配套教程: https://blog.csdn.net/orangehap/category_8914680.html。
跳过实验7。

参考答案:
注:nop
是空指令,不产生任何结果。
nop
的机器码占一个字节。
这个程序有点麻烦!
使用u
命令查看对应的机器码和汇编指令:


编译后,
机器码 |
编译后的指令,后面是目标地址 |
源程序汇编指令 |
EBF0 |
JMP 0008 |
jmp short s |
EBF6 |
JMP 0018 |
jmp short s1 |
下面分析一下转移:

第一条跳转指令:根据上图计算公式,找到第一张DOS图片,
16进制下,8-18=F0,中间负数要转补码表示。
第一条跳转指令:根据上图计算公式,找到第二张DOS图片,
16进制下,18-22=F6,中间负数要转补码表示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| 1. start: mov ax,0 2. s: nop ; nop标号语句,在运行时在代码段中分配一个字节的空间, 3. nop ; 这个字节(空间)的值为90h。
; 操作符 `offset` 的功能是取得标号的偏移地址。 4. mov di,offset s ; 将 s 的偏移地址存到 di 寄存器中 5. mov si,offset s2 ; 将 s2 的偏移地址存到 si 寄存器中 6. mov ax,cs:[si] ; 此行是将cs:[si]内存中的机器码存到ax寄存器中, ; 这个机器码是由编译器将 s2 标号字段中的指令编译而成。 7. mov cs:[di],ax ; 将 ax 中的 s2 标号字段的机器码存放到 s 标号字段中。
8. s0: jmp short s ; 跳转到 s 标号字段处执行代码。
9. s: jmp short s1 ; 根据我们之前的分析, 指令是用相对偏移来表示的 ; 因此执行的操作并不是真的跳转到 s1 这个标号, ; 而是跳转编译时确定的 该指令到 s1 标号的偏移量。 ; 所以我们要分析接下来程序的流程的话 , 就必须先编译程序 , ; 通过查看这条指令的机器代码,才知道偏移量是多少。 ; 然后再根据这个偏移量确定程序下一步应该执行哪里的指令。 ; 根据下图的编译结果 , 可以发现 , ; jmp short s1 在编译后得到的指令是 : EB F6 ; 由上可知,偏移量是 :F6 ; 偏移量是由 补码 来表示的,由书中 附注二 , ; 我们可以算出 F6对应的有符号十进制数为 -10。 ; 从这里,我们可以知道,这条指令是将 ip 的值加上 -10。 ; 那么,我们再看看 ip - 10 指向的地址是哪里呢 ? ; 由下图的编译结果,我们可以知道, ; 它指向的刚好就是 code segment 开始的位置.
10. mov ax,4c00h 11. int 21h ;看到这两句,大家就知道,程序是可以正常返回了
|