nilininimini

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

实验任务:

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

我是根据书本教材提供的思路写的代码;

  书中介绍 利用一个寄存器专门用来存放偏移地址 而且每次循环过程中会增加值

  代码如下:

但是一开始还是遇到两个严重的错误:

第一个是 给出内存单元地址的时候,在字母前没有加零 。就能执行了截图如下:

 

看起来和老师的输出内容是一样的,但是仔细看格式是有偏差的。

为什么给AX 赋值的时候写“0b80h”是对的,但是给bx 赋值“7b8”就是错的 我后来用了“07b8h”就没再报错

 发现是自己对初始化值规则不明确,就按照十六进制的格式写就好了。

 

这样和老师给的差不了多少了,格式也还好,正中间的感觉(编程画图案好惊喜)但是“Press any key to continue”字符出不来,我不太清楚。

后来我网上去找:

加上“ mov ax,4c00h int 21h”就好了 

我原来写的是“mov ax ,4ch” 就不能输出提示字符串。现在好了。

 

 (2)将源代码程序中字数据 0403H→修改为 0441H,再次运行,截图显示运行结果。

 

 

对于利用 mov对数据的操作,需要定义成特定的十六进制 才会使计算机识别吗?也许这里是这样吧。

 

2. 综合使用 loop,[bx],编写完整汇编源程序,实现向内存 0:200~0:23F 依次传送数据 0~63(3FH)。 (1)必做:综合使用 loop, [bx], mov 实现 (2)选做*:利用栈的特性,综合使用 loop,push 实现(限定仅使用 8086 中已学过 指令实现)

  这道题 每次传输的不是一定值,那么我需要两个变量 一个bx用来存放偏移地址 另一个dx 用来进行赋值的数 每次根据循环进行自增(地址在变,值也在变)

 

这是我想到的代码,虽然没有出现语法问题,但是我还是向查看一下值。

后面再看的时候,发现bx的初始值没有给,一开始ds的地址也设置的不对。

我的怀疑很有可能是对的,

 

 貌似这里面的值都没有修改,是因为我地址查看的不对吗?那我怎么知道我做的操作对不对呢?(先看下同学们的实验报告,在交流下好了)

我想应该是在设置数据段地址的时候出现的问题(本身我也不确定数据段地址设置的正不正确)

  位(byte)寄存器是不允许作为栈顶元素被放入的,因为我已开始使用 dl作为进栈的。

(后来知道要用-g命令 后查看才会发现修改了值)

 这是我的的思路。

体验无法立刻得到结果,努力debug的煎熬,努力检查自己思考的漏洞,培养对钻研的耐心。

 

没有考虑源操作数和目标操作数的匹配问题。

后期的错误一直维持在有一个严重错误而集成软件却没有显示错的 这个基调上。很是令人倍感焦急和无奈。

我后来实在写不出来了,就去看了题解。

cx 要用 40h否则会少赋一个值。

题目要求的内存地址是0:200 我用了0:200 但是其实也可以写成0020:X的形式

书P 0:200~0:20b 等于0020:0~0020:b 的形式,显然没有在一开始就反应归来,否则也不会不想到利用偏移地址变化的数字对内存单元进行赋值了。

已经有了些改变

希望循环一次完成可以使用P命令,具体内容是,loop指令时使用P命令

 

上面是少一个值的,下面的是对的。

 

这里我偷懒了。没有练习使用-P命令,之前我截了内存地址的图,里面全是零,也就是内存的数值没有被改变过,但是我要是使用-p或者-g命令之后,里面的是是会改变的(看着里面的值按照预想的方式排列好释然,果然没有经过构建过的代码,就像是没有灵魂注入,而且也不会有)我不知道为什么。

另一个选择不用-p的原因是,我不知道从哪里开始(那我试试吧)

但应该只要在loop 000B 下面使用-P 就可以一次执行完循环(ps:一开始老师和我们说的这个-p和-t的时候我有点反应不过来,因为没有仔细深究过以循环体为单位和 每次循环的情况为单位的区别,所以又有一点点为自己的基础感到自卑。不过好在我后来知道了。)

 (3)下面的程序功能是将“mov ax 4c00h”之前的指令复制到内存0:200处,补全程序。上机调试,跟踪运行结果。

 

上一题 ,下标和所要赋的值是一样的;这一题,栈顶的偏移量是慢慢变小的(内存单元地址的表示)所以一开的的偏移地址就是最大偏移地址和最大值

 

 这是我自己根据上一题修改了之后的结果,虽然还是错的,但是我接下里会查看在出现了错误。

后来又试着修改一下代码:

 

因为栈顶每次是-2 是以一个字为单位的。我后来看了别人的代码。

 

 那么我可不可以不进行Dh的减法,可不可以只减一

 

如果我让栈顶每次减少两个,但是不改变高位寄存器的值 是这样的,我在想,既然高低位寄存器是独立的,而且64也是在8位寄存器可表示的范围之内的,那么高位寄存器应该不影响赋值,但是结果是这样的

那么也就是说只有地位被赋了值,那么也就是说利用两个独立的寄存器的意义在于每次往栈顶放入值的时候,是以字节为单位的。(但是只要让高低位寄存器分别减2就好了吗?如果是这样原因是什么呢?)

是因为有两个十六进制位的原因吗?

高低位值减一的效果是这样的。

可以看到 高低位的赋值是单独的

有点明白之前那个3e3f是怎么回事了。

这里是用两个寄存器分别工作的,高位寄存器不是相邻的所以每次是-2.

 

最终效果:

在这一个实验上,暴露出我对栈存放数据了解上的不足。首先,一次push是将高低位上的数据分别存放在一个独立的寄存器里面的,不过初始化时要考虑内存中使用小端法存储。内存中是我们通常意义上的正序的话,那初始化的时候就应该给逆序。

3. 教材实验 4(3)(P121)

调试下列程序将 “mov  ax,4c00H” 之前的指令复制到内存0:200 处  。

当前的指令:老师讲过。汇编指令默认是从 CS:IP所指向的位置开始运行。那么数据段地址就给CS的段地址好了

(1)复制的是指令,那么就是对应的内存物理地址,,应该是从当前的位置开始到loop所指向的指令之前

(2)字节数 的确定 应该是从开始到loop s的指令书吧,指令条数决定 执行次数。指令个数会放在CX寄存器中

 

借用http://www.mamicode.com/info-detail-2519262.html

程序段的长度决定了要写入数据的长度,也就是循环的次数。

但是是指指令的长度,是要通过反汇编知道的。

 那一开始就只能是 让CX赋值为零才可以指导指令的长度吧。

 

 

cx的一开始的值恐怕不是随意给的0 ,这样才能知道指令的长度。如上图所示指令长度是001B 实际上只要复制到 0017就可以了(INT 21 前就可以了)

 

一开始反汇编出来这个我和吃惊。

总结的话一般都放在每个实验的之后的。不过这里我觉得 设计一个程序之前至少不是那么会的时候可以先对教材知识点进行了解;再开始对编程内容进行思路整理,和框架搭建。先这里。第一个实验任务我可以自己独立完成,比如栈是利用两个独立的寄存器进行存拿数据,CX中的值是指令的长度等等,一些细节的掌握。需要利用时间去积累。

这里给了很多错误的代码,一定程度上会给阅读者造成干扰,也不方便日后进行复习。以后会尽量挑选有针对性的问题。

posted on 2018-11-24 16:11  nilininimini  阅读(222)  评论(0)    收藏  举报