




已阅读5页,还剩74页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
实验一 汇编程序的汇编及运行1实验目的和要求 1、 熟悉汇编程序的汇编、连接、执行过程2、 生成LST文件,查看LST文件3、 生成OBJ文件,修改语法错误4、 生成EXE文件5、 执行2实验的原理和主要仪器设备IBMPC机及其兼容机实验的软件环境是: 操作系统:DOS 2.0以上;调试程序:DEBUG.COM;文本编程程序:EDIT.EXE、WPS.EXE;宏汇编程序:MASM.EXE(或ASM .EXE);连接装配程序:LINK .EXE;交叉引用程序:CREF.EXE(可有可无)。3实验内容及实验数据记录1、将数据段输入,取名1.txt,保存在MASM文件夹下。生成LST文件,(不必连接、运行)用EDIT查看1.LST文件。试回答:DA1,DA2的偏移量分别是多少?COUNT的值为多少?DATA SEGMENT ORG 20H NUM1=8 NUM2=NUM1+10HDA1 DB IBM PC DA2 DB 0AH, 0DHCOUNT EQU $-DA1DATAENDS END2、 输入有错误的文件,修改错误语句。(MASM没有出现错误即可。不必连接、运行。)DATA SEGMENTVAR1DB 0, 25, ODH, 300VAR2 DB 12H, A4H, 6BHVAR3 DB ABCDEFVAR4 DW 1234H, 5678HVAR5 DW 10H DUP(?)DATA ENDSCODE SEGMENT ASSUMECS: CODE, DE: DATABEINGMOV AX, DATA MOV DS, AX LEA SI, VAR5 MOV BX, OFFSET VAR2 MOV SI, 0ABH MOV AX, VAR1+2 MOV BX, SI MOV VAR5+4, VAR4 MOV AH, 4CH INT 21HCODEENDS ENDSTART3、 输入正确的程序,汇编、连接、运行STACKSSEGMENT STACK DW 128 DUP(?)STACKSENDSDATASSEGMENT STRING DB WELCOME!, 13, 10, $DATASENDSCODESSEGMENT ASSUMECS: CODES, DS: DATASSTART: MOVAX, DATAS MOVDS, AX LEA DX, STRING MOVAH, 9 INT 21H MOV AH, 4CH INT 21HCODESENDS ENDSTART4操作方法及实验步骤 编写各代码并存储为源程序asm文件,对其进行汇编、连接。1、Dos进入masm目录2、masm 文件名(对文件进行编译)3、link 文件名(对生成OBJ目标文件进行连接) 4、由dos加载连接后生成的可执行文件来执行程序5实验数据处理和分析(1)(2)如图输入代码编译未能通过,提示出错有9处其中2、3、9行均为符号未定义错误,其中修改ODH中O在十六进制中未定义(不存在)、而A4H以字母开头必须添上数字0)、寄存器中没有DE故而修改之。第十行我们暂且放着,第十四行提示说操作数必须指定大小空间由代码可知,立即数ABH传给内存单元时,必须指定内存大小空间,所以可修改该句为MOV BYTE PTR 0ABH。而15行的错误提示与17行一样均不能找到段寄存器所分配的地址,15行从代码格式上看除了位数不一致外并不是如是的所提错误,而17行是错在两个立即数作为MOV指令的操作数,我们先跳过。下面16行的错误是非法错误的操作数格式,这里两个操作数均是内存单元里的数据,可修改【BX】为BX。由21行错误可知START未定义,之前程序入口中出现了标识符BEING,因此这里改为BEING。同时可知刚刚第十行错误就显而易见了,标识的格式错了。应该为BEING:。部分修改后代码如下:重新编译得如下错误提示第2行中300超出了所分配的看空间字节大小,这里把它改为30,比较之前的出错提示17行和15行的均改变了,这才具体指出了出错原因。这里15行我们就修改AX为AL,匹配两操作数位数。17行中我们为不改变原意可以用如下指令替代:MOV CX,VAR4; MOVVAR5+4,CX;(3)编辑源程序后编译未能通过,提示如图:我们打开源程序看到如图所示:我们之前定义的是DATAS而不是DATAX,修改之。编译通过,我们link进行连接如图:已生成可执行文件3.exe。6. 实验结果(1)编辑源程序后编译生成list文件提示时输入文件名得到1.list文件。打开如图得知:DA1、DA2的偏移量分别是0020H和0026H。(2)通过以上调试分析,最终修正代码,如图已能通过编译。(3)运行3.exe文件,结果如图:7. 总结,质疑,建议,问题讨论 通过此次上机实验进行从编辑源程序到最终的可执行文件的生成并运行。加深了我对程序编译连接运行程序的整个过程的理解,而其中的编译过程让我看到了一个不显眼list文件对之后查错,核实各个指令运行的正确性应该说是程序员的理解与系统处理是否存在出入的重要性,其次让我更加懂得去读懂出错提示,根据提示定位代码的错误之处并修正,再者从实验中发现了重要的一点,要让编译器给出正确或说是更确切的指示,我们应该先保证自己编写的代码语法上的严谨与规范,如17行与15行的错误提示由于程序入口标识符的错误定义而受影响的情况。实验二 顺序程序设计1实验目的和要求(1) 学习使用DEBUG的命令;(2) 使用DEBUG命令在数据段中查看程序运行的结果;(3) 利用DEBUG运行简单的程序段。2实验用的软硬件环境实验的硬件环境是:IBMPC机及其兼容机实验的软件环境是: 操作系统:DOS 2.0以上;调试程序:DEBUG.COM;文本编程程序:EDIT.EXE、WPS.EXE;宏汇编程序:MASM.EXE(或ASM .EXE);连接装配程序:LINK .EXE;交叉引用程序:CREF.EXE(可有可无)。3实验内容及实验数据记录1)输入程序观察寄存器变化 使用DEBUG,将下面的程序段写入内存,逐条执行,观察每条指令执行后,CPU中相关寄存器的内容变化。注意用T命令执行时,CS: IP寄存器的内容MOVAX, 4E20ADDAX, 1416MOVBX, 2000ADDAX, BXMOVBX, AXADDAX, BXMOVAX, 001AMOVBX, 0026ADDAL, BLADDAH, BL ADDBH, AL MOVAH, 0 ADDAL, BL ADDAL, 9C2)下列程序单步运行,注意AL,BX,CX寄存器的变化,并观察数据段字母的变化。DSEGSEGMENTMSG1DBabcDSEGENDSCSEGSEGMENT ASSUMECS: CSEG, DS: DSEGSTART:MOVAX, DSEG MOVDS, AX LEABX, MSG1 MOVCX, 3 S:MOVAL, BX ANDAL, 11011111B ;将AL中的ASCII码的第5位置0,;变成大写字母。 MOV BX, AL INCBX LOOPS MOVAL, 0 MOVAH, 4CH INT 21HCSEGENDS ENDSTART3)程序的跟踪执行操作在DOS下直接输入文件主名就可以执行文件了,有的程序会显示结果,可能执行后什么结果都没有,是因为程序中没有显示命令。那么如何查看程序的运行结果呢?程序执行过程的跟踪操作步骤如下:(1)在DOS下输入:DEBUG 文件名.EXE(2)在DEBUG提示符下输入U命令(3)可以用T命令单步执行指令,执行到 MOV AH, 4CH时结束,也可以用G命令执行整个程序,输入:G=B地址(如:G=0000)(4)用D命令查看程序执行后数据段的变化输入:D K地址:0 (如:D1260:0)在显示的数据中,对照源程序或LST文件查看结果所在的偏移地址的内容。4)输入下面程序,按实验一和上面步骤运行一遍DSEGSEGMENTMSG1DW 7856H,2038HMSG2DW ?DSEGENDSCSEGSEGMENTASSUMECS:CSEG,DS:DSEGSTART:MOVAX,DSEGMOVDS,AXMOVAX,MSG1ANDAX,MSG1+2MOVMSG2,AXMOVAL,0MOVAH,4CHINT21HCSEGENDSENDSTART5)编写调试下面的程序,用DEBUG查看数据段中的结果(1),X,Y,W为字节类型变量,结果存于Z单元,写出数据段和代码段。(无符号数)(2)X,Y为字节类型数,求,写出完整的数据段和代码段,不用乘除指令。(无符号数)4操作方法及实验步骤 1)顺序程序设计(1)、dos进入debug环境,输入a进行程序段写入内存操作,如图:(2)、输入t单步运行跟踪观察到各寄存器的变化如图:(3)、在执行第一条指令MOVAX, 4E20后寄存器AX内容随即变为4E20,而当执行第二条指令ADDAX, 1416后AX变为了6236,运行随后的指令各寄存器的变化完全吻合程序段所实现的功能,并且不难看到IP由0103不断的增加,而CS保留为13A1不变。2)(1)、由文本编辑内容2中的程序段存为II2.txt文件,并masm编译link连接通过,如图:3)& 4)(1)、文本编辑内容4中代码段保存为II4.txt,masm编译link连接通过:(2)、d命令查看MSG2单元中存放的值,如图(执行ANDAX,MSG1+2后,未执行MOVMSG2,AX指令):5)(5-1)编写程序段如下:(1)、分析题目可知数据段中有X、Y、W、Z和常数10、5,所以有:DATADB 5,10XDB 2YDB 8Z DW ?WDB 10(2)、代码段中先执行(W-X)*10有:MOV AL,W SUB AL,XCBW;之前误解为乘指令操作数需16位故而出现此错误。MUL DATA+1之后加5结果除于X+Y有: ADD AX,DB;DATA错输入为DBMOV CL,X ADD CL,Y DIV CL(3)、所以有最初代码如下(错误) DSEGSEGMENTDATADB5,10XDB2YDB8ZDW ?WDB 10DSEGENDSCSEGSEGMENTASSUMECS:CSEG,DS:DSEGSTART:MOVAX,DSEGMOVDS,AXMOVAL,WSUBAL,XCBWMULDATA+1ADDAX,DBMOVCL,XADDCL,YDIVCLCSEGENDSENDSTART(5-2)编写程序段如下(1)、分析题目可知数据段中有X、Y、Z和常数8、2、16,所以有:DATADB 8,2,16XDB 5YDB 3Z DW ?(2)、代码段先实现(X+X)*8有如下:MOV AL,XADD AL,AL;实现X+XMOV CL,3SHL AL,CL ;逻辑左移3位实现乘8 实现(X-Y)*2有:MOV BL,XSUB BL,Y ;实现X-YMOV CL,1SHL BL,CL ;逻辑左移1位实现乘2实现分子部分(X+X)*8-(X-Y)*2:SUB AL,BL实现除于16并把结果送Z:MOV CL,4SHR AL,CL ;逻辑右移4位实现除于16MOV Z,AL(3)、程序段通过编译并并成功链接,如图:5实验数据处理与分析(1)、直接运行II2.exe文件可以看到dos窗口未显示任何信息,于是debug II2.exe文件跟踪执行,如图:(2)、t命令单步运行观察到IP在不断得递增指向下一条指令:执行第一和第二次时CX递减,可以看到CX=0002,CX=0001,a变为了大写A,b变为了大写B:同理之后可以看到CX=0000时执行循环结束完成字符串大小写转换。5-1)(1)、编译未能通过如图:(2)、修改未定义标识符DB为DATA,编译仍然出错:(3)、操作数位数不一致,分析可知在执行(W-X)*10后结果存放在AX中为能满足除法指令要求被除数为字节时,默认隐含除数为(AX),于是修改代码段如下:START:MOV AX,DSEGMOV DS,AXMOV AL,WSUB AL,XMUL DATA+1MOV BX,AX ;注1MOV AL,DATA ;注2CBW ;注3ADD AX,BX ;实际上注释的指令完全可以用ADD AL,DATA代替,之前是在多此一举,自己在给自己添麻烦。MOV CL,XADD CL,YDIV CLCSEG ENDSEND START(4)、最终编译连接成功如下:(1)、 debug II5b.exe 跟踪程序,u反汇编可以看到数据段段地址为076A;再从lise文件中查看得Z得偏移量为0002,如图:(2)、因此执行完程序段后可以看到AX=0704为即是AL=04,结果正确;6. 实验结果1)对比之前我们程序段录入时前段显示的正是13A1且“:”之后的数字和IP的变化一致,可知cpu在执行指令时是通过CS代码寄存器定位代码段所处内存单元和改变IP指令寄存器中的地址(偏移量)来具体指定所要执行的指令。2)& 3)程序段实现了转输入字符串转小写为大写的功能:通过d命令跟踪到数据段的变化对比程序段可知通过该指令 ANDAL, 11011111B可知在原字符的ASCII码中的第五位逻辑与上0其他为不变,其值相当于减小了25=32实现了小写到大写的转换,同理若要将大写转换为小写只需将该句改写成OR AL,00100000(加上25=32)即可。4)查看list文件不难得知MSG2偏移地址为0004,如图:执行MOVMSG2,AX指令后d查看1415:0004即是MSG2单元内容为2010:5-1)DEBUG查看到AX结果为0508即商为8余数为5如图:由list可查看到z的偏移量为0004:D076A:0004命令查看到如图Z中为空,遗忘了将AX数据传送给了Z;代码段中补充指令MOV Z,AX执行d076A:0004最终得到Z中结果0805即是商8余5,如图:5-2)由之前操作后可执行d076A:0002即可查看Z单元数据为04即是所求商如图:7. 质疑,建议,问题讨论,总结实验中我掌握了编写简单的程序,并且高效得运用debug进行调试,有效地跟踪指令观察各指令所实现得功能,并熟练运用其查看数据段的内容。在编写并调试程序得环节中,由于对指令得不熟悉导致了一些不必要得麻烦,如第五题1中得设计,由于对部分隐含寄存器操作的不确定使得在符号扩展方面上出现问题最后竟绕了个圈。程序最终虽能通过编译并连接运行得到正确得结果,但总认为缺少些什么 ,如在对DS装入时AX的改变有可能对后面得指令造成影响,因而就必须对其装入后其他指令使用其前进行清零操作XOR AX,AX。而至于DOS的功能调用方面由于在这里对程序影响不大,同时略去MOV AH,4CH ; INT21H;的一个好处就是让我更好了解到t跟踪运行多条指令的好处并能很好得运用它,使我更深刻理解了调试程序对整个程序设计得重要。总而言之该次实验让我看到了自己很多不足并学到了很多,很好得巩固升华了理论知识。 实验三 分支循环程序设计1实验目的和要求1、学习调试程序,查找逻辑错误;2、学习分支语句的编程和调试;3、学习循环语句的编程和调试。 2实验用的软硬件环境实验的硬件环境是:IBMPC机及其兼容机实验的软件环境是: 操作系统:DOS 2.0以上;调试程序:DEBUG.COM;文本编程程序:EDIT.EXE、WPS.EXE;宏汇编程序:MASM.EXE(或ASM .EXE);连接装配程序:LINK .EXE;交叉引用程序:CREF.EXE(可有可无)。3实验内容及实验数据记录6、 有10个数,统计正数的个数,存放在变量M中中。经过汇编后,形成EXE文件。在DEBUG中,先用G0命令执行程序,用D命令查看M单元的内容,会发现结果不正确。用单步执行命令T0,单步执行程序,查找程序中的逻辑错误,注意每一次循环中AL寄存器中值的变化是否正确。(AL寄存器中存放正数的个数)DSEGSEGMENT MSGDB 4, -2, -6, 0, 5, 67, 8, -3, 5, 6MDB ?DSEGENDSCSEGSEGMENT ASSUMECS: CSEG, DS: DSEGSTART:MOVAX, DSEG MOVDS, AX MOVCX, 10 MOVAL, 0 LEASI, MSGL1:MOVBL, SI CMP BL, 0 JBENEXT INCALNEXT:INCSI LOOPL1 MOVM, AL MOVAL, 0 MOVAH, 4CH INT21HCSEGENDS ENDSTART数据段中是一组无符号数,将最小数存放在M单元中。按上题方法查找一处逻辑错误。DSEGSEGMENT MSGDB 13, 15, 7, 25, 24M DB ?DSEGENDSCSEGSEGMENT ASSUMECS: CSEG, DS: DSEGSTART:MOVAX, DSEG MOVDS, AX MOVCX, 4 MOVAL, MSG MOVSI, OFFSET MSG+1L1:CMP AL, SI JBNEXT MOVAL, SINEXT:LOOP L1 MOVM, AL MOV AL, 0 MOVAH, 4CH INT 21HCSEGENDS END START7、 编程:在首地址为BUF开始的内存单元中存有10个字节数,求其中0的个数,并将结果存于RESULT中。8、 编程:,Ai,Bi为字节型无符号数,分别存于NUM1和NUM2开始的连续存储单元中,结果存于REST单元中。4操作方法及实验步骤1)编辑代码,编译连接均可通过,亦能正常运行。 DSEGSEGMENT MSGDB 4, -2, -6, 0, 5, 67, 8, -3, 5, 6MDB ?DSEGENDSCSEGSEGMENT ASSUMECS: CSEG, DS: DSEGSTART:MOVAX, DSEG MOVDS, AX MOVCX, 10 MOVAL, 0 LEASI, MSGL1:MOVBL, SI CMP BL, 0 JBENEXT INCALNEXT:INCSI LOOPL1 MOVM, AL MOVAL, 0 MOVAH, 4CH INT21HCSEGENDS ENDSTART查看list文件得知M单元偏移量为000A,如图:g命令运行后,d命令查看(d1415:000A)得知M中值为09即是正数有9个,显然是不正确的如图 2)同一编辑如下代码进行编译连接运行均正常;DSEGSEGMENT MSGDB 13, 15, 7, 25, 24M DB ?DSEGENDSCSEGSEGMENT ASSUMECS: CSEG, DS: DSEGSTART:MOVAX, DSEG MOVDS, AX MOVCX, 4 MOVAL, MSG MOVSI, OFFSET MSG+1L1:CMP AL, SI JBNEXT MOVAL, SINEXT:LOOP L1 MOVM, AL MOV AL, 0 MOVAH, 4CH INT 21HCSEGENDS END START由指令MSGDB 13, 15, 7, 25, 24M DB ?可计算0005为M的的偏移量。如图,g命令运行后,d命令查看(d1415:0005)知M中值为0DH=13即最小的数是13,显然不正确。3)3.1据题意有如下要求a定义:首地址BUF,结果RESULTb数据:10个字节数c实现:查找0的个数3.2分析满足要求满足a&b有: BUF DB 4, -2, -6, 0, 5, 0, 8, -3, 5, 0 RESULT DB ?实现c:MOV CX,10 ;控制循环次数MOVAL,0 ;AL用于存放临时个数,清零CMMP:CMPSI,0 ;比较SI所指与0JNENEXT;SI所指不等0跳入NEXT标号所指指令INCAL;SI所指等于0,AL加1NEXT: INCSI;指针下一指向下一个即将比较的数LOOPCMMP;循环比较直至CX=0;3.4最初程序代码DATASEGMENT;数据段DATA开始BUF DB 4,-2,-6,0,5,0,8,-3,5,0;分配字节空间首地址BUFRESULT DB ?;存放结果DATA ENDS;数据段DATA结束CODESEGMENT;代码段CODE开始ASSUME DS:DATA,CS:CODE;DATA,CODE对应挂钩DS,CSSTART:MOVAX,DATA;程序入口MOVDS,AX ;数据段装入MOV CX,10;初始循环次数MOVAL,0;AL用于存放0的个数,初始为0CMMP:CMPSI,0;当前指针指向的数据与0比较JNENEXT;所指数据不等于0跳至NEXT标号处指令INCAL ;相等则AL加1NEXT: INCSI;NEXT入口,指针加1下移指向下一个数LOOPCMMP;进入循环CMMP,继续比较当前数MOVRESULT,AL;将结果传送至RESULT中MOV AL,0;AL清零MOV AH,4CHINT21H;调用dos返回dos界面功能CODEENDS;代码段CODE开始ENDSTART;程序结束4)4.1据题意有如下要求a 存在两组数据每组8个,均为无符号字节数b 每组数据分别以NUM1、NUM2为首地址,结果存放在REST中c 实现两组数据两两相乘后共8组数据,最终求总和4.2分析处理满足要求满足a&b: NUM1 DB 1,2,3,4,5,6,7,8NUM2 DB 8,7,6,5,4,3,2,1RESTDW ?(由于结果可能很大故而开辟word空间)实现c:首先是进行两两相乘,可以分别用一指针SI,DI同时自上而下取数进行相乘并将结果临时存放于AX,其次将下一次(当前)结果与AX中上一次结果相加,通过循环便可达到实现要求c中的功能,由于第一次结果的存放不再循环之内,可以将其单独列出,这样难免显得程序冗长,拖沓。因此可以优化其,将AX先初始化为0,把第一次相乘也列入循环中。问题便可以很好得到解决。这里有一个问题就是简单的通过SI和DI来进行相乘时忽略了一个问题就是两个操作数不能同时为内存单元的数,因此必须借助于寄存器临时存储其中一个数。而AL在每一次乘法操作时均被作为隐含操作数而用到因而可直接由AL来存放其中一个数,而存放和的AX这里应由其他寄存器暂代之如BX。所以优化上图后如下:DI 4.3根据以上设想设计流程图:(loop的错误理解导致了这里循环的控制上有问题,其中的注(1)应该放在注(2)之后loop之前)4.4最初程序代码(错误)DATASEGMENT;数据段DATA开始NUM1 DB 1,2,3,4,5,6,7,8;第一组数分配字节空间首地址NUM1NUM2 DB 8,7,6,5,4,3,2,1;第二组数分配字节空间首地址NUM2REST DW ?;存放结果DATA ENDS;数据段DATA结束CODESEGMENT;代码段CODE开始ASSUME DS:DATA,CS:CODE;DATA,CODE对应挂钩DS,CSSTART:MOVAX,DATA;程序入口MOVDS,AX;数据段装入 MOV AX,0;AX清零MOV BX,0;BX清零LEA SI,NUM1 ;将NUM1首地址传送给SILEA DI,NUM2 ;将NUM2首地址传送给DINEXT:ADD BX,AX ;BXAX+BXMOVAL,SI;将SI所指单元数据传送给ALMULDI;DI所指单元数据与AL相乘结果存放在AXINCSI;指针SI下移,指向NUM1下一个数INCDI;指针DI下移,指向NUM2下一个数LOOPNEXT;循环跳至NEXT标号处直至CX自减至0MOV AH,4CHINT21H;调用dos返回dos界面功能CODEENDS;代码段CODE开始ENDSTART;程序结束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指令执行0017指令INCSI,可从跟踪结果看到0015指令INCAl依然被执行了,结果当然是正数个数AL=2多加了1不符合实际,如图:由此已经找到了出错位置即在此无需继续跟踪。1.3分析并修改错误我们知道-2显然符合“小于(below)或者等于(equal)零”的条件,为什么程序却判断-2比零大呢,可知因该句条件并没错语法上也正确,现在唯一的问题给忽略了就是符号了,我们知道数据的存储方式是补码形式,-2的补码为FE而程序条件是BE是对无符号数的操作FE自然是大于0了,由此我们改该指令为有符号操作即JLENEXT或者JNGNEXT,重新编译连接并运行程序最终得正确结果6 。2)2.1单步调试找到错误t单步跟踪得到如图在执行调入第一个数到AL后并比较SI如图SI是01即指向数15,由代码可知此时符合JMP条件B(below)跳转至0014指令(段内) LOOPL1即进入循环进行下一次比较CMP AL SI,这里可以看到SI依旧是01仍指向15,并没有下移,由此可知程序出错在于SI未能下移指向下一个即将要比较的数。从代码上看也容易得知程序至终都未曾移动SI指向。2.2分析并改错结合程序代码和题目要求,为了找到最小的数并把他存放在M中,程序基本完成了比较部分和存放功能,唯一的错误是在SI的移动未实现,可知在进入循环L1,CMP比较之前因该找到下一个比较的数,而无论比较结果如何下移SI操作均需要执行到,因此在NEXT: 里LOOPL1之前添加INCSI实现指针自加功能。具体如下:NEXT:INCSILOOPL13)3.1编译以上代码出错提示未能通过,出错如下:提示11行中操作数未指定大小,查看代码知SI为内存单元数据,必须指定大小是byte还是word。3.2修改其为:CMPBYTE PTR SI,0重新编译,如图已能顺利通过编译并连接。3.3进入debug环境u命令反汇编得知数据段地址076A,RESULT偏移量000A如图4)4.1编译最初代码未能通过提示如下图:4.2分析并改错第10行超出内存范围,查看代码为:可知指令并没错,错误在于注释中的“;”应该为“;”后面的随之修改后,重新编译,依然存在错误如图提示未指定操作数大小:我们知道在数据传送指令中有目的操作数若是内存单元数据和源操作数是立即数时必须指定大小,而若有一是寄存器数据是可无需指定。疏忽了在单操作数的乘除指令也同样必须指定大小使之位数一致。为什么出现这样情况可想而知因为乘除指令的隐含操作数所在寄存器可能是AL或AX,其选择决定于源操作数的位数。因此修改原指令为“MUL BYTE PTR DI ”。继续重新编译终于顺利通过编译并连接如图:4.3debug调试检查结果g运行程序,要进行d查看时才发现忘了将结果传送给REST,在原代码LOOP指令后添加指令:MOVREST BX,重新回到编译阶段,继续编译,还好正常通过了。完成以上操作后,u反汇编得到数据段首地址076A和REST偏移量0010后,d076a:0010查看REST中内容为6A8C=(6A为高地址所在)如图:通过计算器计算得120对比之得知结果不正确。4.4再次分析并改错结合流程图仔细浏览推敲程序,基本上并没问题,最终结果如此大,一个可能便是加上了不必要即定义段之外的数据,首先想到的是所用寄存器的初始化问题,检查之均无误(还是漏了检查CX);其次是一个严重的问题,可能是循环超出了范围(在初始化了CX后,由循环控制理解错误导致),核实代码果真是这样,在第一次执行到NEXT指令时不是由LOOP跳转过来的而此时SI和DI均已经指向了各自数据段首,在执行第一次LOOP时SI,DI执行了加1操作,CX这才减1,而CX减至1时,SI和DI均已指向了最后一个数,最后结果便是加上了0008*0011的值。T单步跟踪验证如下:看来还是没仔细的检查,CX=45竟忘了初始化为8了。流程图有了,可代码 中却遗漏了。所以之前的猜想可能是错的,先修改之( 在MOV AX,0之前添上指令MOVCX,8 )。重新编译连接运行,查看一下结果是70相比正确结果少了8。T命令跟踪之:如上图,第一组乘积8正确加到BX;可以推断是最后一组乘积遗漏了。跟踪发现至CX=1时,LOOP并没有执行到如下图,看来是自己理解错了,LOOP是先执行CX自减操作,再判断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)修改后重复以上步骤得到最终结果为78H=120答案正确如下图:7. 总结,质疑,建议,问题讨论通过此次实验才发现自己有多么的不足,题目并不难甚至可以说是很简单。可就这么简单的几道题由于自己对一些指令没有深透的理解,给自己找了不少苦头,一二题很容易跟踪就可以找到出错位置分析修改之。至于第三题中未能一次编译通过是自己形而上学没有牢记操作数位数一致的指令规则。一个晚上大半时间是死在了最后一题上。先是又一次犯了第三题中同样的错误,原因是自己并没有真正深入理解操作数位数一致的规则,因单操作数而忽略了它,光是记住还是不行,该错误的再次出现让我深刻理解了该规则,希望以后仍铭记。后是CX忘了初始化,忘了,添上了就没话说,竟然一直自以为是的认为已经初始化过了而把自己引向了另一个方向,胡乱猜了一大堆可能性,引自己到了另一胡同里。直到debug调试T跟踪后才发现,竟是简单的CX未初始化,而LOOP的理解错误的的确确给自己添了不少麻烦,不过通过T跟踪很快就发现了。 此次实验虽然磕磕绊绊的,但很大程度上提升了我的分析问题解决问题的能力,更重要的是让我的思维更开放了,如最后一题的羁绊,虽然猜想错误了,但让我在以后同类的问题中有了个预先的警示。并且深入问题后让我发现,一个问题牵扯出了没有发生但该注意的其他问题,如在最后一题我所犯错误的修改上,第一中改法可以(调试过),是因为在该题中0011所指向的也是数据,并且在该数据段内。而如果REST在其他地方定义的话,或者说0010已经是该数据段结尾了,那么第一种改法很可能就会是错的了。实验四 子程序设计1实验目的和要求1、学习子程序的编写,主子程序的调用2、不同模块间程序的调用和调试2实验用的软硬件环境实验的硬件环境是:IBMPC机及其兼容机实验的软件环境是: 操作系统:DOS 2.0以上;调试程序:DEBUG.COM;文本编程程序:EDIT.EXE、WPS.EXE;宏汇编程序:MASM.EXE(或ASM .EXE);连接装配程序:LINK .EXE;交叉引用程序:CREF.EXE(可有可无)。3实验内容及实验数据记录1、数据段中的3个字符,调用子程序将其逐个显示出来。子程序的功能是显示一个字符。单步执行,观察IP的变化DATASEGMENTMAGDB ABCDATAENDSCODESEGMENTASSUMECS: CODE, DS: DATASTART:MOVAX, DATA MOVDS, AX MOVSI, 0 MOVCX, 3LL:MOV DL, MAGSICALL MADD INCSI LOOPLLMOVAH, 4CHINT21HMADDPROCMOV AH, 02H INT 21HRETMADDENDPCODEENDS END START2、阅读S31.ASM和S32.ASM两个模块中的程序,并分别汇编,然后连接成一个可执行文件S31.EXE。具体步骤如下:MASM S31.ASM(分别汇编)MASM S32.ASMLINK S31 S32 (将两个文件连接成为一个文件名为S31)S31.EXE (运行)3、编程:利用主程序调用子程序,比较BUF1和BUF2缓冲区中不相等的字符,并将不相等的字符显示出来。(也可以将找到的不相等字符逐个显示,用INT 21H的02功能调用)4、编程:子程序搜索指定字符缓冲区中是否有n,如果有用y替代。调用子程序将BUF1,BUF2,BUF3中的n全部用y替代4操作方法及实验步骤1-1)文本编辑程序保存V1.asm,编译并连接后debug调试V1.exe。跟踪如下u反汇编观察CALL指令所在程序段偏移量为000F而且Call到哪显而易见是0019即Mov AH,02与源程序一致而RET指令偏移量为001D但从中我们并不能得知其具体执行过程。1-2)t单步跟踪,图为执行CALL指令前各个寄存器的状态及查看SS:IP(d0769:0000)即栈顶内容为零。BP始终都为0实际上直到目前都没用到该堆栈。1-3)继续单步执行,此时IP指向下一条指令CALL 0019。即执行该指令,结果如下可看到SP变为了FFFE可知执行该指令的同时堆栈处于忙碌的变更中。之后IP直接指向CALL 所指0019。d0769:fffe查看栈顶内容如下高向低读为0012由之前的反汇编得知0012正是INCSI指令的偏移量,而该指令位于Call指令的下一条。1-4)由此我们推断RET指令的作用就是弹出栈顶内容至IP来使得程序接着运行执行CALL指令后的程序。同样T单步执行观察如下很明显执行RET后IP指向了0012。SP又指向了栈底。得以证实了CALL调用子程序是通过堆栈保护了现场进入子程序,之后再通过RET恢复到了原状态2-1)单独阅读两个程序模块似乎毫无瓜葛
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 政治●重庆卷丨2023年重庆市普通高中学业水平选择性考试政治试卷及答案
- 浙江省嘉兴市多校2023-2024学年四年级下学期数学期末检测(含答案)
- 初中英语八年级下册统编教案 uunit5
- 从军直播活动方案
- 仓储质量活动年活动方案
- 仙桃市送喜报活动方案
- 代发留存率活动方案
- 代表代表活动方案
- 代账公司获客活动方案
- 以建平台办活动方案
- 电气施工管理
- 视唱练耳知到智慧树章节测试课后答案2024年秋四川音乐学院
- 五年级法制教育课件
- 手术室护理质量控制指标
- 小儿泌尿道感染护理查房
- 住院患儿实施院内转运临床实践指南2023版课件
- GB/T 44450-2024光学和光子学光学材料和元件0.78 μm~25 μm红外光谱用光学材料特性
- 代持股协议书
- 2024至2030年中国绿甲醇行业市场前景预测与发展趋势研究报告
- 2024年天津市中考英语真题卷及答案
- JGJ/T235-2011建筑外墙防水工程技术规程
评论
0/150
提交评论