ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

实验2 汇编源程序编写与汇编调试.pdf

2020-11-05 19:01:57  阅读:229  来源: 互联网

标签:汇编 code mov ds pdf 所示 ax bx 源程序


一、实验结论

1. 实验任务1

使用任意一款文本编辑器,编写8086汇编源程序ex1.asm。源代码如下:
 1 ;ex1.asm
 2 assume cs:code
 3 code segment
 4     mov ax, 0b810h
 5     mov ds, ax
 6     
 7     mov byte ptr ds:[0], 1h
 8     mov byte ptr ds:[1], 1h
 9     mov byte ptr ds:[2], 2h
10     mov byte ptr ds:[3], 2h
11     mov byte ptr ds:[4], 3h
12     mov byte ptr ds:[5], 3h
13     mov byte ptr ds:[6], 4h
14     mov byte ptr ds:[7], 4h
15 
16     mov ah, 4ch
17     int 21h
18 code ends
19 end
使用masm、link对ex1.asm进行汇编、链接,得到可执行文件ex1.exe,运行效果如下所示:

使用debug工具对程序ex1.exe进行调试: 1)使用debug加载可执行文件ex1.exe后,使用d命令查看程序段前缀PSP所占的256个字节,结果如下图所示:

2)结合上图确定寄存器CX的值为31h,即可使用u命令对ex1.exe进行精确反汇编,结果如下图所示:

3)使用g命令执行到程序退出执行之前(即源码文件中line16之前),结合上图所示,只需执行到偏移地址为 2dh之前,执行结果如下图所示:

2. 实验任务2

使用任意一款文本编辑器,编写8086汇编源程序ex2.asm。源代码如下: 
 1 ;ex2.asm
 2 assume cs:code
 3 code segment
 4     mov ax, 0b810h
 5     mov ds, ax
 6 
 7     mov bx, 0h
 8     mov ax, 0101h
 9     mov cx, 4h
10 s:  mov [bx], ax
11     add bx, 2h
12     add ax, 101h
13     loop s
14 
15     mov ah, 4ch
16     int 21h
17 code ends
18 end
使用masm、link对ex2.asm进行汇编、链接,得到可执行文件ex2.exe,运行效果如下所示:

使用debug工具对程序ex2.exe进行调试: 1)结合可执行文件中寄存器CX的值,使用u命令对ex2.exe进行精确反汇编,执行结果如下图所示:

2)灵活使用 t命令、p命令、g命令,对ex2.exe进行调试。(不一定要单步,有些地方可以用g命令,一次执行多行汇编指令),运行结果如下图所示: * 首先使用 g命令执行到图中红色标记处,执行结果如下图所示:

* 接下来使用 t命令来一步一步查看循环体所实现的功能,一次循环的效果如下图所示:

 分析一次循环体所作的工作:将 ax寄存器的值赋给内存地址为 ds:[bx] 的内存单元,一次赋值一个字;  其中 bx从 0h开始每次自增 2h,而 ax从 0101h开始每次自增0101h。循环一共执行四次,那么汇总一下,  循环所做的功能:将 0101 0202 0303 0404这些数据依次写入内存地址为 B810:0000 ~B810:0007的内存单元中。  下面验证分析是否正确:

3)将ex2.asm中line9 mov cx, 4 改成 mov cx, 8并把文件重命名为ex3.asm,保存后重新汇编、链接、运行,执行结果如下图所示:

 由于改变cx 寄存器的值即改变 loop循环指令执行的次数,同时其他初始数据未作相关变动,可以分析此汇编代码实现的功能:  将 0101 0202 0303 0404 0505 0606 0707 0808 这些数据依次写入内存地址为 B810:0000 ~B810:000f 的内存单元中。  下面验证分析是否正确:

4)思考:结合上述实验和观察,分析、对比ex2.asm和ex1.asm,它们实现的是否是相同的功能和效果?在具体实现上有什么不同?  答:从实现功能以及程序运行的结果来看,ex1.asm 和 ex2.asm 其实是一致的,都是向内存地址为 B810:0000~B810:0007的连续    内存单元写入相同的数据;但就具体实现而言,ex1.asm 的实现方式就是直接使用mov指令依次写入数据,如果要写入的数据    足够多,那会导致汇编代码繁杂冗余;由于写入的数据都是有规律的,同时也是向一段连续的内存地址写入数据,那么此时就    可以借助循环即 loop指令来防止代码冗余而实现的功能都是一致的,这便是ex2.asm的实现原理。

3. 实验任务3

任务:综合使用 loop,[bx],编写完整汇编程序,实现向内存b800:07b8开始的连续16个字单元重复填充字数据 0237H。 实现以上任务的源代码如下所示:
 1 ;ex4.asm
 2 assume cs:code
 3 code segment
 4     mov ax, 0b800h
 5     mov ds, ax
 6     mov bx, 07b8h
 7     mov ax, 0237h
 8     mov cx, 16h
 9 
10 x:  mov [bx], ax
11     add bx, 2h
12     loop x
13     
14     mov ah, 4ch
15     int 21h
16 code ends
17 end
使用masm、link对ex4.asm进行汇编、链接,得到可执行文件ex4.exe,运行效果如下所示:

 运行 ex4.exe,运行效果如下图所示:

* 把填充的字数据,从0237H 改成 0239H,再次保存后,汇编、链接、运行,运行效果如下图所示:

* 把填充的字数据,从0237H 改成0437H,再次保存后,汇编、链接、运行,运行效果如下图所示:

猜测并分析,这个字数据中高位字节里存放的是什么信息,低位字节里存放的是什么信息?   答:列出所有写入的数据以及显示结果:    A.数据: 0237H;结果:绿色的“ ? ”    B.数据: 0239H;结果:绿色的“ 9 ”    C.数据: 0437H;结果:红色的“ ? ”   结合以上列出的数据以及结果,可以知道在存储这些字的内存地址中,高位字节存储的是字符的颜色,   低位字节存储的是字符的二进制表示。

4. 实验任务4

任务:编写完整汇编源程序,实现向内存0:200~0:23F依次传送数据0~63(3FH)。 1)综合使用 [bx] 和 loop,编写汇编源程序实现,源程序如下:
 1 assume cs:code
 2 code segment
 3     mov ax, 0
 4     mov ds, ax
 5     mov bx, 200h
 6     mov ax, 0
 7     mov cx, 40h
 8 
 9 s:  mov [bx] ,al
10     inc ax
11     inc bx
12     loop s
13 
14     mov ax, 4c00h
15     int 21h
16 code ends
17 end

 以上源程序运行的具体过程如下图所示:


 2)利用栈的特性,综合使用 loop,push(限定仅使用8086中已学过指令实现)编写源程序,源程序如下所示:
 1 assume cs:code
 2 code segment
 3     mov ax, 0
 4     mov ss, ax
 5     mov sp, 0240h
 6     mov ah, 3fh
 7 
 8 s: push ax
 9     dec ah
10     inc sp
11     loop s
12 
13     mov ah, 4ch
14     int 21h
15 code ends
16 end

 以上源程序运行的具体过程如下图所示:

 

5. 实验任务5

 任务:下面的程序功能是将“ mov ax, 4c00h ”之前的指令复制到内存 0:200 处,补全程序。上机调试,跟踪运行结果。  实现以上任务的源代码如下:(其中带下划线的是需要我们补全的代码)
 1 assume cs:code
 2 code segment
 3     mov ax, _cs_
 4     mov ds, ax
 5     mov ax, 0020h
 6     mov es, ax
 7     mov bx, 0
 8     mov cx, _17h_
 9 
10 s:  mov al,[bx]
11     mov es:[bx], al
12     inc bx
13     loop s
14 
15     mov ax, 4c00h
16     int 21h
17 code ends
18 end
 从汇编代码整体观之,要想完成第一个空的填写,就需要明白 ds寄存器应该指向哪里,由于本任务是想要  汇编实现代码自己复制自己到内存的另一块,那么很明显该复制的数据应该来自代码本身所对应的机器码。  所以此时 ds寄存器的值应该等于 cs寄存器的值,这样才可以从内存单元取出机器码复制到另外一个内存块;  接下来需要完成第二空,我们知道 cx寄存器是用来控制程序循环的次数。从循环体中可以看出,每次循环  都取出一个字节的机器码并且复制到另一块内存单元上,所以我们必须得知道“ mov ax, 4c00h ”之前的指令  对应的机器码要占用多少字节,这样才能控制循环次数。遗憾的是,我们并不知道各类机器码所占用的字节数。  为了获取“ mov ax, 4c00h ”之前的指令对应的机器码占用字节数,我们随意使用一个数据(假设使用“ 1122h ”)  将第二空填上,让其通过编译,链接,然后使用 debug工具来反编译汇编代码,这样就可以获取确实的机器码  字节数了,具体执行如下图所示:

根据上图的测试结果,我们将循环次数 17h 或者23(十进制表示)填入第二空,下面进行程序代码的测试,测试过程如下图所示:

标签:汇编,code,mov,ds,pdf,所示,ax,bx,源程序
来源: https://www.cnblogs.com/Togankez/p/13922972.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有