ImageVerifierCode 换一换
格式:DOCX , 页数:18 ,大小:273.29KB ,
资源ID:4344202      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/4344202.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(汇编实验三分支循环程序设计.docx)为本站会员(b****4)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

汇编实验三分支循环程序设计.docx

1、汇编实验三分支循环程序设计福建农林大学东方学院信息工程类实验报告系: 计算机系 专业: 电子信息工程 年级: 10 姓名: 学号: 1050302103 实验课程: 汇编语言 实验室号:_ 实验设备号: 实验时间: 指导教师签字: 成绩: 实验三 分支循环程序设计1实验目的和要求1、学习调试程序,查找逻辑错误;2、学习分支语句的编程和调试;3、学习循环语句的编程和调试。 2实验用的软硬件环境实验的硬件环境是:IBMPC机及其兼容机实验的软件环境是: 操作系统:DOS 2.0以上;调试程序:DEBUG.COM;文本编程程序:EDIT.EXE、WPS.EXE;宏汇编程序:MASM.EXE(或ASM

2、 .EXE);连接装配程序:LINK .EXE;交叉引用程序:CREF.EXE(可有可无)。3实验内容及实验数据记录1. 有10个数,统计正数的个数,存放在变量M中中。经过汇编后,形成EXE文件。在DEBUG中,先用G0命令执行程序,用D命令查看M单元的内容,会发现结果不正确。用单步执行命令T0,单步执行程序,查找程序中的逻辑错误,注意每一次循环中AL寄存器中值的变化是否正确。(AL寄存器中存放正数的个数)DSEG SEGMENT MSG DB 4, -2, -6, 0, 5, 67, 8, -3, 5, 6 M DB ? DSEG ENDS CSEG SEGMENT ASSUME CS: C

3、SEG, DS: DSEG START: MOV AX, DSEG MOV DS, AX MOV CX, 10 MOV AL, 0 LEA SI, MSG L1: MOV BL, SI CMP BL, 0 JBE NEXT INC AL NEXT: INC SI LOOP L1 MOV M, AL MOV AL, 0 MOV AH, 4CH INT 21H CSEG ENDS END START2. 数据段中是一组无符号数,将最小数存放在M单元中。按上题方法查找一处逻辑错误。 DSEG SEGMENT MSG DB 13, 15, 7, 25, 24 M DB ? DSEG ENDS CSEG

4、 SEGMENT ASSUME CS: CSEG, DS: DSEG START: MOV AX, DSEG MOV DS, AX MOV CX, 4 MOV AL, MSG MOV SI, OFFSET MSG+1 L1: CMP AL, SI JB NEXT MOV AL, SI NEXT: LOOP L1 MOV M, AL MOV AL, 0 MOV AH, 4CH INT 21H CSEG ENDS END START3. 编程:在首地址为BUF开始的内存单元中存有10个字节数,求其中0的个数,并将结果存于RESULT中。4. 编程:,Ai,Bi为字节型无符号数,分别存于NUM1和N

5、UM2开始的连续存储单元中,结果存于REST单元中。4操作方法及实验步骤1)编辑代码,编译连接均可通过,亦能正常运行。 DSEG SEGMENT MSG DB 4, -2, -6, 0, 5, 67, 8, -3, 5, 6 M DB ? DSEG ENDS CSEG SEGMENT ASSUME CS: CSEG, DS: DSEG START: MOV AX, DSEG MOV DS, AX MOV CX, 10 MOV AL, 0 LEA SI, MSG L1: MOV BL, SI CMP BL, 0 JBE NEXT INC AL NEXT: INC SI LOOP L1 MOV M

6、, AL MOV AL, 0 MOV AH, 4CH INT 21H CSEG ENDS END START查看list文件得知M单元偏移量为000A,如图:g命令运行后,d命令查看(d1415:000A)得知M中值为09即是正数有9个,显然是不正确的如图 2)同一编辑如下代码进行编译连接运行均正常; DSEG SEGMENT MSG DB 13, 15, 7, 25, 24 M DB ? DSEG ENDS CSEG SEGMENT ASSUME CS: CSEG, DS: DSEG START: MOV AX, DSEG MOV DS, AX MOV CX, 4 MOV AL, MSG M

7、OV SI, OFFSET MSG+1 L1: CMP AL, SI JB NEXT MOV AL, SI NEXT: LOOP L1 MOV M, AL MOV AL, 0 MOV AH, 4CH INT 21H CSEG ENDS END START由指令MSG DB 13, 15, 7, 25, 24 M DB ?可计算0005为M的的偏移量。如图,g命令运行后,d命令查看(d1415:0005)知M中值为0DH=13即最小的数是13,显然不正确。3)3.1据题意有如下要求a定义:首地址BUF,结果RESULTb数据:10个字节数c实现:查找0的个数3.2分析满足要求满足a&b有: BU

8、F DB 4, -2, -6, 0, 5, 0, 8, -3, 5, 0 RESULT DB ?实现c: MOV CX,10 ;控制循环次数 MOV AL,0 ;AL用于存放临时个数,清零 CMMP: CMP SI,0 ;比较SI所指与0 JNE NEXT ;SI所指不等0跳入NEXT标号所指指令 INC AL ;SI所指等于0,AL加1 NEXT: INC SI ;指针下一指向下一个即将比较的数 LOOP CMMP ;循环比较直至CX=0; 3.4最初程序代码 DATA SEGMENT ;数据段DATA开始 BUF DB 4,-2,-6,0,5,0,8,-3,5,0;分配字节空间首地址BUF

9、 RESULT DB ? ;存放结果 DATA ENDS ;数据段DATA结束 CODE SEGMENT ;代码段CODE开始 ASSUME DS:DATA,CS:CODE ;DATA,CODE对应挂钩DS,CS START: MOV AX,DATA ;程序入口 MOV DS,AX ;数据段装入 MOV CX,10 ;初始循环次数 MOV AL,0 ;AL用于存放0的个数,初始为0 CMMP: CMP SI,0 ;当前指针指向的数据与0比较 JNE NEXT ;所指数据不等于0跳至NEXT标号处指令 INC AL ;相等则AL加1 NEXT: INC SI ;NEXT入口,指针加1下移指向下一

10、个数 LOOP CMMP ;进入循环CMMP,继续比较当前数 MOV RESULT,AL ;将结果传送至RESULT中 MOV AL,0 ;AL清零 MOV AH,4CH INT 21H ;调用dos返回dos界面功能 CODE ENDS ;代码段CODE开始 END START ;程序结束4)4.1据题意有如下要求a 存在两组数据每组8个,均为无符号字节数b 每组数据分别以NUM1、NUM2为首地址,结果存放在REST中c 实现两组数据两两相乘后共8组数据,最终求总和4.2分析处理满足要求满足a&b: NUM1 DB 1,2,3,4,5,6,7,8 NUM2 DB 8,7,6,5,4,3,2

11、,1 REST DW ?(由于结果可能很大故而开辟word空间)实现c: 首先是进行两两相乘,可以分别用一指针SI,DI同时自上而下取数进行相乘并将结果临时存放于AX,其次将下一次(当前)结果与AX中上一次结果相加,通过循环便可达到实现要求c中的功能,由于第一次结果的存放不再循环之内,可以将其单独列出,这样难免显得程序冗长,拖沓。因此可以优化其,将AX先初始化为0,把第一次相乘也列入循环中。问题便可以很好得到解决。这里有一个问题就是简单的通过SI和DI来进行相乘时忽略了一个问题就是两个操作数不能同时为内存单元的数,因此必须借助于寄存器临时存储其中一个数。而AL在每一次乘法操作时均被作为隐含操作

12、数而用到因而可直接由AL来存放其中一个数,而存放和的AX这里应由其他寄存器暂代之如BX。所以优化上图后如下:DI 4.3根据以上设想设计流程图:(loop的错误理解导致了这里循环的控制上有问题,其中的注(1)应该放在注(2)之后loop之前) 4.4最初程序代码(错误) DATA SEGMENT ;数据段DATA开始 NUM1 DB 1,2,3,4,5,6,7,8;第一组数分配字节空间首地址NUM1 NUM2 DB 8,7,6,5,4,3,2,1;第二组数分配字节空间首地址NUM2 REST DW ? ;存放结果 DATA ENDS ;数据段DATA结束 CODE SEGMENT ;代码段CO

13、DE开始 ASSUME DS:DATA,CS:CODE ;DATA,CODE对应挂钩DS,CS START: MOV AX,DATA ;程序入口 MOV DS,AX ;数据段装入 MOV AX,0 ;AX清零 MOV BX,0 ;BX清零 LEA SI,NUM1 ;将NUM1首地址传送给SI LEA DI,NUM2 ;将NUM2首地址传送给DI NEXT: ADD BX,AX ;BXAX+BX MOV AL,SI ;将SI所指单元数据传送给AL MUL DI ;DI所指单元数据与AL相乘结果存放在AX INC SI ;指针SI下移,指向NUM1下一个数 INC DI ;指针DI下移,指向NUM

14、2下一个数 LOOP NEXT ;循环跳至NEXT标号处直至CX自减至0 MOV AH,4CH INT 21H ;调用dos返回dos界面功能 CODE ENDS ;代码段CODE开始 END START ;程序结束5调试过程1)1.1单步调试程序跟踪找到程序的错误。如图:第一次调入si=04到BL并进行BL与0比较指令由当前的1416:0013执行后执行0015指令并没有立即跳至0017指令INC Al可知第一次比较得与正确处理执行正数个数加一,指针下移操作1.2进入循环继续跟踪调入BL第二个数si=-2=FEH,再一次比较0此时符合条件JBE中的below即小于应该跳过0015指令执行00

15、17指令INC SI,可从跟踪结果看到0015指令INC Al依然被执行了,结果当然是正数个数AL=2多加了1不符合实际,如图:由此已经找到了出错位置即在此无需继续跟踪。1.3分析并修改错误我们知道-2显然符合“小于(below)或者等于(equal)零”的条件,为什么程序却判断-2比零大呢,可知因该句条件并没错语法上也正确,现在唯一的问题给忽略了就是符号了,我们知道数据的存储方式是补码形式,-2的补码为FE而程序条件是BE是对无符号数的操作FE自然是大于0了,由此我们改该指令为有符号操作即JLE NEXT或者JNG NEXT,重新编译连接并运行程序最终得正确结果6 。2)2.1单步调试找到错

16、误t单步跟踪得到如图在执行调入第一个数到AL后并比较SI如图SI是01即指向数15,由代码可知此时符合JMP条件B(below)跳转至0014指令(段内) LOOP L1即进入循环进行下一次比较CMP AL SI,这里可以看到SI依旧是01仍指向15,并没有下移,由此可知程序出错在于SI未能下移指向下一个即将要比较的数。从代码上看也容易得知程序至终都未曾移动SI指向。2.2分析并改错结合程序代码和题目要求,为了找到最小的数并把他存放在M中,程序基本完成了比较部分和存放功能,唯一的错误是在SI的移动未实现,可知在进入循环L1,CMP比较之前因该找到下一个比较的数,而无论比较结果如何下移SI操作均

17、需要执行到,因此在NEXT: 里LOOP L1之前添加INC SI实现指针自加功能。具体如下: NEXT: INC SI LOOP L1 3)3.1编译以上代码出错提示未能通过,出错如下:提示11行中操作数未指定大小,查看代码知SI为内存单元数据,必须指定大小是byte还是word。3.2修改其为:CMP BYTE PTR SI,0重新编译,如图已能顺利通过编译并连接。3.3进入debug环境u命令反汇编得知数据段地址076A,RESULT偏移量000A如图4)4.1编译最初代码未能通过提示如下图:4.2分析并改错第10行超出内存范围,查看代码为:可知指令并没错,错误在于注释中的“;”应该为“

18、;”后面的随之修改后,重新编译,依然存在错误如图提示未指定操作数大小:我们知道在数据传送指令中有目的操作数若是内存单元数据和源操作数是立即数时必须指定大小,而若有一是寄存器数据是可无需指定。疏忽了在单操作数的乘除指令也同样必须指定大小使之位数一致。为什么出现这样情况可想而知因为乘除指令的隐含操作数所在寄存器可能是AL或AX,其选择决定于源操作数的位数。因此修改原指令为“MUL BYTE PTR DI ”。继续重新编译终于顺利通过编译并连接如图:4.3debug调试检查结果g运行程序,要进行d查看时才发现忘了将结果传送给REST,在原代码LOOP指令后添加指令:MOV REST BX,重新回到编

19、译阶段,继续编译,还好正常通过了。完成以上操作后,u反汇编得到数据段首地址076A和REST偏移量0010后,d076a:0010查看REST中内容为6A8C=(6A为高地址所在)如图:通过计算器计算得120对比之得知结果不正确。4.4再次分析并改错结合流程图仔细浏览推敲程序,基本上并没问题,最终结果如此大,一个可能便是加上了不必要即定义段之外的数据,首先想到的是所用寄存器的初始化问题,检查之均无误(还是漏了检查CX);其次是一个严重的问题,可能是循环超出了范围(在初始化了CX后,由循环控制理解错误导致),核实代码果真是这样,在第一次执行到NEXT指令时不是由LOOP跳转过来的而此时SI和DI

20、均已经指向了各自数据段首,在执行第一次LOOP时SI,DI执行了加1操作,CX这才减1,而CX减至1时,SI和DI均已指向了最后一个数,最后结果便是加上了0008*0011的值。T单步跟踪验证如下:看来还是没仔细的检查,CX=45竟忘了初始化为8了。流程图有了,可代码 中却遗漏了。所以之前的猜想可能是错的,先修改之( 在MOV AX,0之前添上指令MOV CX,8 )。重新编译连接运行,查看一下结果是70相比正确结果少了8。T命令跟踪之:如上图,第一组乘积8正确加到BX;可以推断是最后一组乘积遗漏了。跟踪发现至CX=1时,LOOP并没有执行到如下图,看来是自己理解错了,LOOP是先执行CX自减

21、操作,再判断CX是否为零才执行跳转与否的。因此可以有两种修改方法,一是将CX初始为9,这样避免大幅度修改代码。而修改代码也不难,错误的原因是ADD BX,AX放在了AL*DI前导致少加了一次。直接将其移到MUL DI之后便可。这里选择后者虽然修改前面的流程图麻烦,给自己个教训,好下次别在这“想当然”的地方再摔倒。6. 实验结果以下均已在debug环境中。1)g运行程序,d1415:000A查看M内容为06即有6个是正数正确,如图2)g运行程序,d1415:0005查看M内容为07即最小数是7正确,如图3)g运行程序,d076a:000a查看RESULT内容为03即有3个数为0正确,如图4)修改

22、后重复以上步骤得到最终结果为78H=120答案正确如下图:7. 总结,质疑,建议,问题讨论通过此次实验才发现自己有多么的不足,题目并不难甚至可以说是很简单。可就这么简单的几道题由于自己对一些指令没有深透的理解,给自己找了不少苦头,一二题很容易跟踪就可以找到出错位置分析修改之。至于第三题中未能一次编译通过是自己形而上学没有牢记操作数位数一致的指令规则。一个晚上大半时间是死在了最后一题上。先是又一次犯了第三题中同样的错误,原因是自己并没有真正深入理解操作数位数一致的规则,因单操作数而忽略了它,光是记住还是不行,该错误的再次出现让我深刻理解了该规则,希望以后仍铭记。后是CX忘了初始化,忘了,添上了就

23、没话说,竟然一直自以为是的认为已经初始化过了而把自己引向了另一个方向,胡乱猜了一大堆可能性,引自己到了另一胡同里。直到debug调试T跟踪后才发现,竟是简单的CX未初始化,而LOOP的理解错误的的确确给自己添了不少麻烦,不过通过T跟踪很快就发现了。 此次实验虽然磕磕绊绊的,但很大程度上提升了我的分析问题解决问题的能力,更重要的是让我的思维更开放了,如最后一题的羁绊,虽然猜想错误了,但让我在以后同类的问题中有了个预先的警示。并且深入问题后让我发现,一个问题牵扯出了没有发生但该注意的其他问题,如在最后一题我所犯错误的修改上,第一中改法可以(调试过),是因为在该题中0011所指向的也是数据,并且在该数据段内。而如果REST在其他地方定义的话,或者说0010已经是该数据段结尾了,那么第一种改法很可能就会是错的了。

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1