实验四

 

实验结论:

练习一:

综合使用 loop,[bx],编写完整汇编程序,实现向内存 b800:07b8 开始的连续 16 字单元重复填充字数据 0403H

第一步:

结合loop指令的特性,设计并写出代码(代码如下):

assume cs:code

         code segment

         mov ax,0b800h

         mov ds,ax

         mov bx,07b8h

         mov cx,0fh

         mov [bx],0403h

         s: add bx,2h

            mov [bx],0403h

           loop s

         mov ax,4c00h

         int 21h

code ends

end

第二步:

使用批处理文件对源文件进行汇编、连接(如下图):

 

 

第三步:

清屏并运行连接以后生成的可执行文件loop.exe(执行结果如下):

 

 

出现了16个心形字符,说明向b800:07b8以及向后的15个存储单元写入了十六次0403H。

代码运行成功。

练习二:

综合使用 loop,[bx],编写完整汇编源程序,实现向内存 0:200~0:23F 依次传送数据 0~63(3FH)

方法1:综合使用 loop, [bx], mov 实现:

第一步:

设计代码(如下):

assume cs:code

         code segment

         mov ax,0020H

         mov ds,ax

         mov bx,0H

         mov cx,40H

         s: mov [bx],bl

            add bx,1H

            loop s

         mov ax,4c00H

         int 21H

code ends

end

第二步:

使用批处理文件对源文件进行汇编、连接(如下图):

 

 

第三步:

清屏并运行连接以后生成的可执行文件loop1.exe,由于loop1.exe实现的是向0:200~0:23F的内存单元写入数据,所以在屏幕上无法看出结果,所以对loop1.exe进行debug,并通过d命令来查看相应内存单元中的值是否已经被改变(操作如下图):

 

 

可见,相应地址单元的数据已经被改写为0~3F

代码运行成功。

方法二:使用栈的特性(先进后出,先入栈的后出栈)来完成:

第一步:

设计代码(如下):

assume cs:code

         code segment

         mov ax,0020H

         mov ss,ax

         mov sp,40H

         mov bx,3F3EH

         mov cx,20H

         s: push bx

            sub bl,2H

            sub bh,2H

            loop s

         mov ax,4c00H

         int 21H

code ends

end

代码思想:题目说要我使用栈来实现向0:200~0:23F中写入相应的数据,想到栈就会想到它的先进后出的特性,同时又想到题目要求是传字节型数据,而使用栈就默认传送字型数据,乍一看,好像不能使用栈来实现这一个功能,但是仔细思考,字就是两个字节,那我就可以利用这个性质,以一次传送“两个字节”来代替一次传一个“字”的方法来实现,实现方法就是:我将我需要压栈的数据以高位字节和低位字节的形式来组成一个字数据,再进行压栈,如初始状态,我将bx中的值改为4F4EH(结合了我需要压栈的数据和字型数据存储的“小端法”)这样首次压栈进去就是4E和4F,然后我分别将bl和bh两个寄存器中的值减2,为下一次压栈做准备,类比方法1,区别就在于有一个整体的思想(在此题中我想给你三块钱等价于我先给你一块钱,再给你两块钱等价于我左手拿1块钱,右手拿两块钱,然后同时给你)和循环的次数问题:方法一中因为是一个字节一个字节的赋值所以有几个存储单元就循环几次(40H),但是在方法二中,一次赋值两个字节,所以循环次数(20H)只需要方法一中的一半即可。

注意:我在使用方法二实现的时候,一开始并没有注意到循环次数减半的问题,即我仍然保留cx=40H,发现输出的结果也是正确的,但是要说明,虽然我查看的0:200~0:23F这一段的数据确实赋值正确,但是已经发生了栈顶超界,只是超界的那一部分,并不在为了检查程序正确性而查看的那一段内存单元的范围之内,所以我认为c=40H时代码运行正确,实际上是不对的。

在改正了错误之后再次运行loop2.exe,并对其debug(如下图):

 

 

可见,相应地址单元的数据同样被改写为0~3F

代码运行成功。

练习三:

教材实验 4(3)

第一步:补全代码(如下):

assume cs:code

         code segment

         mov ax,cs  ;依据:因为当前执行的段是由cs指示的。

         mov ds,ax

         mov ax,0020H

         mov es,ax

         mov bx,0

         mov cx,0017H

;依据:因为经过debug发现代码总共占字节数为1ch个字节所以排除掉mov ax,4c00H和 int 21H两行所占的5个字节就只剩0017h个字节需要复制了。

         s:mov al,[bx]

           mov es:[bx],al

           inc bx

           loop s

           mov ax,4c00H

           int 21H

code ends

end

划线处为需要补全的地方。

第二步:汇编、连接、执行、debug

 

 

可以发现:pp.asm中的在mov ax,4c00h之前的代码确实已经被拷贝到了0:200及以后。

代码运行成功。

 

总结与体会:

练习一和练习二:

熟悉了用汇编语言的编程过程是如何的,熟悉了[bx]和loop指令的使用。

了解到究竟如何使用栈来进行数据的传送,怎么去用,以何种形式去用。

练习三:

熟悉了在CPU中只是当前执行的段的地址的寄存器是cs而不是cs里的值,以及段前缀的使用。

 

 

posted @ 2018-11-16 19:45  yys_c  阅读(223)  评论(0编辑  收藏  举报