您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 项目/工程管理 > 第4章-汇编语言程序设计
第4章汇编语言程序设计〔习题4.1〕简答题〔解答〕①当同一个程序被操作系统安排到不同的存储区域执行时,指令间的位移没有改变,目标地址采用相对寻址可方便操作系统的灵活调度。②数据通信时,数据的某一位用做传输数据的奇偶校验位,数据中包括校验位在内的“1”的个数恒为奇数,就是奇校验;恒为偶数,就是偶校验。③无符号数和有符号数的操作影响两组不同的标志状态位,故判断两个无符号数和有符号数的大小关系要利用不同的标志位组合,所以有对应的两组指令。④双分支结构中两个分支体之间的JMP指令,用于实现结束前一个分支回到共同的出口作用。⑤完整的子程序注释可方便程序员调用该子程序,子程序注释包括子程序名、子程序功能、入口参数和出口参数、调用注意事项和其他说明等。⑥子程序保持堆栈平衡,才能保证执行RET指令时当前栈顶的内容是正确的返回地址。主程序也要保持堆栈平衡,这样才能释放传递参数占用的堆栈空间,否则多次调用该子程序可能就致使堆栈溢出。⑦“传值”是传递参数的一个拷贝,被调用程序改变这个参数不影响调用程序;“传址”时,被调用程序可能修改通过地址引用的变量内容。⑧INCLUDE语句包含的是文本文件、是源程序文件的一部分;INCLUDELIB语句包含的是子程序库文件。⑨取长补短。⑩Windows程序在运行时需要加载其配套的动态链接库DLL文件,当其没有被搜索到时就会提示不存在。〔习题4.2〕判断题〔解答〕①对②错③错④错⑤错⑥对⑦对⑧错⑨对⑩错〔习题4.3〕填空题〔解答〕①相对寻址,间接寻址,直接寻址,间接寻址②1256H,3280H③3721H,1④EAH⑤循环初始,循环控制⑥REPT1标号的地址⑦TESTENDP,ENDM⑧EBP⑨PUBLIC,EXTERN⑩38H0DH0AH〔习题4.4〕为了验证例题4-1程序的执行路径,可以在每个标号前后增加显示功能。例如使得程序运行后显示数码1234。〔解答〕jmplabl1;相对寻址nopmoveax,'?'calldispclabl1:moveax,'1'calldispcjmpnearptrlabl2;相对近转移nopmoveax,'?'calldispclabl2:moveax,'2'calldispcmoveax,offsetlabl3jmpeax;寄存器间接寻址nopmoveax,'?'calldispclabl3:moveax,'3'calldispcmoveax,offsetlabl4movnvar,eaxjmpnvar;存储器间接寻址nopmoveax,'?'calldispclabl4:moveax,'4'calldispc〔习题4.5〕使用“SHREAX,2”将EAX中的D1位移入CF标志,然后用JC/JNC指令替代JZ/JNZ指令完成例题4-3的功能。〔解答〕moveax,56h;假设一个数据shreax,2;D1位移入CF标志jncnom;D1=0条件成立,转移...;余同原程序〔习题4.6〕执行如下程序片断后,CMP指令分别使得5个状态标志CF、ZF、SF、OF和PF为0还是为1?它会使得哪些条件转移指令指令Jcc的条件成立、发生转移?moveax,20hcmpeax,80h〔解答〕CF=1ZF=0SF=1OF=0PF=1可以使得条件成立、发生转移的指令有:JCJSJPJNZJNO〔习题4.7〕将例题4-4程序修改为实现偶校验。建议进一步增加显示有关提示信息的功能,使得程序具有更加良好的交互性。〔解答〕includeio32.inc.datamsg1byte'Pleaseinputacharacter:',0msg2byte'TheASCIIcodeofthecharateryouenteredis:',0msg3byte'Thecodewithevenparityis:',0.codestart:moveax,offsetmsg1calldispmsgcallreadccalldispcrlfmovebx,eaxmoveax,offsetmsg2calldispmsgmoveax,ebxcalldispbbcalldispcrlfandal,7fhjpnextoral,80hnext:movebx,eaxmoveax,offsetmsg3calldispmsgmoveax,ebxcalldispbbexit0endstart〔习题4.8〕在采用奇偶校验传输数据的接收端应该验证数据传输的正确性。例如,如果采用偶校验,那么在接收到的数据中,其包含“1”的个数应该为0或偶数个,否则说明出现传输错误。现在,在接收端编写一个这样的程序,如果偶校验不正确显示错误信息,传输正确则继续。假设传送字节数据、最高位作为校验位,接收到的数据已经保存在Rdata变量中。〔解答〕;数据段Rdatabyte57h;保存接收的数据errorbyte'Error!',0;代码段moval,Rdataandal,0ffh;标志PF反映“1”的个数jpdone;个数为偶数,正确继续moveax,offseterror;个数为奇数,显示出错calldispmsgdone:〔习题4.9〕指令CDQ将EAX符号扩展到EDX,即:EAX最高为0,则EDX=0;EAX最高为1,则EDX=FFFFFFFFH。请编程实现该指令功能。〔解答1〕testeax,8000h;测试最高位jznext1;最高位为0(ZF=1),转移到标号NEXT1movedx,0ffffffffh;最高位为1,顺序执行:设置EDX=FFFFFFFFHjmpdone;无条件转移,跳过另一个分支next1:movdx,0;最高位为0转移到此执行:设置EDX=0done:〔解答2〕使用移位指令更好。roleax,1rcredx,1saredx,31roreax,1〔习题4.10〕编程,首先测试双字变量DVAR的最高位,如果为1,则显示字母“L”;如果最高位不为1,则继续测试最低位,如果最低位为1,则显示字母“R”;如果最低位也不为1,则显示字母“M”。〔解答〕;数据段dvardword57h;代码段moveax,dvartesteax,80000000hjnznextltesteax,1jnznextrmoval,'M'jmpdonenextl:moval,'L'jmpdonenextr:moval,'R'done:calldispc〔习题4.11〕编写一个程序,先提示输入数字“InputNumber:0~9”,然后在下一行显示输入的数字,结束;如果不是键入了0~9数字,就提示错误“Error!”,继续等待输入数字。〔解答〕;数据段inmsgbyte'Inputnumber(0~9):',0ermsgbyte0dh,0ah,'Error!Inputagain:',0;代码段moveax,offsetinmsg;提示输入数字calldispmsgagain:callreadc;等待按键cmpal,'0';数字0?jberdispcmpal,'9';数字9?jaerdispcalldispcrlfcalldispcjmpdoneerdisp:moveax,offsetermsgcalldispmsgjmpagaindone:〔习题4.12〕有一个首地址为ARRAY的20个双字的数组,说明下列程序段的功能。movecx,20moveax,0movesi,eaxsumlp:addeax,array[esi]addesi,4loopsumlpmovtotal,eax〔解答〕求这20个双字的和,保存在TOTAL变量,不关进心进位和溢出。〔习题4.13〕编程中经常要记录某个字符出现的次数。现编程记录某个字符串中空格出现的次数,结果保存在SPACE单元。〔解答〕;数据段stringbyte'DoyouhavefunwithAssembly?',0;以0结尾的字符串spacedword?;代码段movesi,offsetstringxorebx,ebx;EBX用于记录空格数again:moval,[esi]cmpal,0jzdonecmpal,20h;空格的ASCII码是20Hjnenext;不相等、不是空格,转移incbx;相等、是空格,空格个数加1next:incesijmpagain;继续循环done:movspace,ebx;保存结果〔习题4.14〕编写计算100个16位正整数之和的程序。如果和不超过16位字的范围(65535),则保存其和到WORDSUM,如超过则显示‘Overflow!’。〔解答〕;数据段arrayword2005,2008,98dup(1394);假设100个16位正整数wordsumword?errorbyte'Overflow!',0;代码段andebx,0movecx,100xorax,axagain:addax,array[ebx*2]jcoverincebxloopagainmovwordsum,axover:moveax,offseterrorcalldispmsg〔习题4.15〕在一个已知长度的字符串中查找是否包含“BUG”子字符串。如果存在,显示“Y”,否则显示“N”。〔解答〕;数据段stringbyte'Ifyoufindanyerrorintheprogram,youcanDEBUGit.'count=sizeofstringbugbyte'BUG';代码段movecx,countmovedi,offsetstringL1:movesi,offsetbugpushedimovedx,sizeofbugLN:moval,[esi]cmp[edi],aljneL2incesiincedidecedxjneLNpopedimoval,'Y'jmpL3L2:popediincediloopL1moval,'N'L3:calldispc〔习题4.16〕主存中有一个8位压缩BCD码数据,保存在一个双字变量中。现在需要进行显示,但要求不显示前导0。由于位数较多,需要利用循环实现,但如何处理前导0和数据中间的0呢?不妨设置一个标记。编程实现。〔解答〕;数据段bcddword00371002h;代码段movesi,bcdcmpesi,0jnzgoonmoval,'0'calldispcjmpdonegoon:movecx,8xorebx,ebx;EBX=0,表示可能是前导0again:rolesi,4moveax,esiandeax,0fh;EAX低4位保存当前要显示的BCD码cmpebx,0;EBX≠0,说明不是前导0,要显示jnzdisp;EBX=0,说明可能是前导0cmpeax,0jznext;EAX=0,说明是前导0,不显示movebx,1;EAX≠0,没有前导0了,令EBX=1≠0disp:addal,30hcalldispcnext:loopagaindone:〔习题4.17〕已知一个字符串的长度,剔除其中所有的空格字符。请从字符串最后一个字符开始逐个向前判断、并进行处理。〔解答〕;数据段stringbyte'Letushaveatry!',0dh,0ah,0;代码段movecx,sizeofstringcmpecx,2jbdoneleaeax,string;显示处理前的字符串calldispmsgmovesi,ecxdecesioutlp:cmpstring[esi],'';检测是否是空格jnznext;不是空格继续循环movedi,esi;是空格,进入剔除空格分支dececxinlp:incedimoval,string[edi];前移一个位置movstring[edi-1],alcmpedi,ecxjbinlpnext:decesi;继续进行cmpesi,0jnzoutlp;为0结束leaeax,string;显示处理后的字符串calldispmsgdone:〔习题4.18〕第3章习题3.14在屏幕上显示ASCII表,现仅在数据段设置表格缓冲区,编程将ASCII代码值填入留出位置的表格,然后调用显示功能实现(需
本文标题:第4章-汇编语言程序设计
链接地址:https://www.777doc.com/doc-5820028 .html