




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
16。32位微机原理、汇编语言及接口技术(第二版)第三章课后习题答案。>第3章3.1:汇编语言有什么特点 解: 汇编语言是一种以处理器指令系统为基础的低级程序设计语言,它采用助记符表达指令操作码,采用标识符号表示指令操作数,可以直接、有效地控制计算机硬件,因而容易创建代码序列短小、运行快速的可执行程序3.2编写汇编语言源程序时,一般的组成原则是什么?解: (1)完整的汇编语言源程序由段组成 (2)一个汇编语言源程序可以包含若干个代码段、数据段、附加段或堆栈段,段与段之间的顺序可随意排列 (3)需独立运行的程序必须包含一个代码段,并指示程序执行的起始点,一个程序只有一个起始点 (4)所有的可执行性语句必须位于某一个代码段内,说明性语句可根据需要位于任一段内 (5)通常,程序还需要一个堆栈段3.3MODEL伪指令是简化段定义源程序格式中必不可少的语句,它设计了哪7种存储模式?各用于创建什么性质的程序?解: 存储模式特点TINYCOM类型程序,只有一个小于64KB的逻辑段(MASM6.x支持)SMALL小应用程序,只有一个代码段和一个数据段(含堆栈段),每段不大于64KBCOMPACT代码少、数据多的程序,只有一个代码段,但有多个数据段MEDIUM代码多、数据少的程序,可有多个代码段,只有一个数据段LARGE大应用程序,可有多个代码段和多个数据段(静态数据小于64KB)HUGE更大应用程序,可有多个代码段和多个数据段(对静态数据没有限制)FLAT32位应用程序,运行在32位80x86CPU和Windows9x或NT环境3.4如何规定一个程序执行的开始位置,主程序执行结束应该如何返回DOS,源程序在何处停止汇编过程?解: 开始位置:用标号指明 返回DOS:利用DOS功能调用的4CH子功能3.7DOS支持哪两种可执行程序结构,编写这两种程序时需要注意什么?解:(1).EXE程序 程序可以有多个代码段和多个数据段,程序长度可以超过64KB 通常生成EXE结构的可执行程序(2).COM程序 只有一个逻辑段,程序长度不超过64KB 需要满足一定条件才能生成COM结构的可执行程序(MASM6.x需要采用TINY模式)3.8举例说明等价“EUQ”伪指令和等号“=”伪指令的用途解: 符号定义伪指令有“等价EQU”和“等号=”: 符号名EQU数值表达式 符号名EQU<字符串> 符号名=数值表达式 EQU用于数值等价时不能重复定义符号名,但“=”允许有重复赋值。例如: X=7 ;等效于:Xequ7 X=X+5 ;“XEQUX+5”是错误的3.9给出下列语句中,指令立即数(数值表达式)的值(1)moval,23hAND45hOR67h(2)movax,1234h/16+10h3:movax,23hSHL44:moval,‘a’and(NOT(‘a’-‘A’))5:movax,(76543LT32768)XOR7654h解: (1)al=67h (2)ax=133h,dx=4h (3)ax=0230h (4)al=41h (4)ax=7654h3.10画图说明下列语句分配的存储空间及初始化的数据值(1)byte_vardb‘abc’,10,10h,‘EF’,3dup(-1,?,3,dup(4))(2:)word_vardw10h,-5,3,dup(?)解: (1)41h42h43h1010h45h46h-1?444-1?444-1?444(2)10h00h0fbh0ffh??????3.11请设置一个数据段,按照如下要求定义变量:(1)my1b为字符串常量,表示字符串“personalComputer”(2)my2b为用十进制数表示的字节变量,这个数的大小为20(3)my3b为用十六进制数表示的字节变量,这个数的大小为20(4)my4b为用二进制数表示的字节变量,这个数的大小为20(5)my5w为20个未赋值的字变量(6)my6c为100的符号常量(7)my7c为字符串常量,代替字符串“personalComputer”解:.data my1bdb'PersonalComputer' my2bdb20 my3bdb14h my4bdb00010100b my5wdw20dup(?) my6c=100 my7c=<'PersonalComputer'>3.12希望控制变量或程序代码在段中的偏移地址,应该使用哪个伪指令?解: 利用定位伪指令控制,如org,even,align3.13名字和符号有什么属性?解: 包括逻辑地址和类型两种属性。3.14设在某个程序中有如下片段,请写出每条传送指令执行后寄存器AX的内容:;数据段Org100hVarwdw1234h,5678hVarbdb3,4Varddd12345678hBuffdb10dup(?)Messdb‘hello’;代码段Movax,offsetmessMovax,typebuff+typemess+typevardMovax,sizeofvarw+sizeofbuff+sizeofmessMovax,lengthofvarw+lengthofvard解: ;数据段 org100h varw dw 1234h , 5678h varb db 3 , 4 vard dd 12345678h buff dd 10 dup(?) mess db 'Hello' ;代码段 mov ax , offset varb + offset mess mov ax , type buff + type mess + type vard mov ax , sizeof varw+sizeof buff+sizeofmess mov ax , lengthof varw+lengthof vard3.15假设myword是一个字变量,mybyte1和mybyte2是两个字节变量,指出下列语句中的具体错误原因。(1)movbyteptr{bx},1000(2)movbx,offsetmyword{si}(3)cmpmybyte1,mybyte2(4)movmybyte1,al+1(5)subal,myword(6)jnzmyword解: (1)1000超过一个字节所能表达的最大整数 (2)SI应为偶数 (3)两个内存单元不能直接运算 (4)应改为[al+1] (5)条件转移指令后面应接标号,而不是变量3.16编写一个程序,把从键盘输入的一个小写字母用大写字母显示出来解: movah,1 ;只允许输入小写字母 int21h subal,20h ;转换为大写字母 movdl,al movah,2 int21h ;显示3.17已知用于LED数码管的显示代码表为:LEDtabledb0c0h,0f9h,0a4h,0b0h,99h,92h,82h,0f8hdb80h,90h,88h,83h,0c6h,0c1h,86h,8eh它依次表示0~9,A~F这16个数码的显示代码。现编写一个程序实现将lednum中的一个数字(0~9,a~f)转换成对应的LED显示代码解: movbx,offsetLEDtable moval,lednum xlat3.18编制一个程序,把变量bufX和bufY中较大者存入bufZ;若两者相等,则把其中之一存入bufZ中。假设变量存放的是8位有符号数。解: movax,bufX cmpax,bufY jaedone movax,bufYdone: movbufZ,ax3.19为有符号16位数,请将它们的符号状态保存在signX,即:如果变量值大于等于0,保存0;如果X小于0,保存-1。编写该程序。设变量bufX解: .modelsmall .stack .databufX dw-7signX db? .code .startup cmpbufX,0 ;testbufX,80h jlnext ;jnznext movsignX,0 jmpdonenext: movsignX,-1done: .exit0 end3.20bufX、bufY和bufZ是3个有符号16进制数,编写一个比较相等关系的程序(1)如果这3个数都不相等,则显示0(2)如果这三个数中有两个数相等,则显示1(3)如果这三个数都相等,则显示2解: movdl,’2 movax,bufX cmpax,bufY jenext1 decdlnext1: cmpax,bufZ jenext2 decdlnext2: movah,2 int21h3.21例3.7中,如果要实现所有为1的位都顺序执行相应的处理程序段(而不是例题中仅执行最低为1位的处理程序段),请写出修改后的代码段?解: ;代码段 moval,number movbx,0 ;BX←记录为1的位数restart: cmpal,0 ;AL=0结束 jzdoneagain: shral,1 ;最低位右移进入CF jcnext ;为1,转移 incbx ;不为1,继续 jmpagainnext: pushax pushbx shlbx,1 ;位数乘以2(偏移地址要用2个字节单元) jmpaddrs[bx] ;间接转移:IP←[table+BX] ;以下是各个处理程序段fun0: movdl,'0' jmpdispfun1: movdl,'1' jmpdispfun2: movdl,'2' jmpdispfun3: movdl,'3' jmpdispfun4: movdl,'4' jmpdispfun5: movdl,'5' jmpdispfun6: movdl,'6' jmpdispfun7: movdl,'7' jmpdisp ;disp: movah,2 ;显示一个字符 int21h popbx popax jmprestartdone: …编制程序完成12H、45H、0F3H、6AH、20H、0FEH、90H、0C8H、57H和34H等10个字节数据之和,并将结果存入字节变量SUM中(不考虑溢出和进位)。;wjxt322.asm .modelsmall .stack .datab_data db12h,45h,0f3h,6ah,20h,0feh,90h,0c8h,57h,34h ;原始数据num equ10 ;数据个数sum db? ;预留结果单元 .code .startup xorsi,si ;位移量清零 xoral,al ;取第一个数 movcx,num ;累加次数again: addal,b_data[si] ;累加 incsi ;指向下一个数 loopagain ;如未完,继续累加 movsum,al ;完了,存结果 .exit0 end3.23求主存0040h:0开始的一个64KB物理段中共有多少个空格?;wjxt323.asm .modelsmall .codestart: movax,0040h ;送段地址 movds,ax movsi,0 ;偏移地址 movcx,si ;计数(循环次数) xorax,ax ;空格计数器清零again: cmpbyteptr[si],20h ;与空格的ASCII码比较 jnenext ;不是空格,转 incax ;是空格,空格数加1next: incsi ;修改地址指针 loopagain ;cx=cx-1,如cx=0退出循环 .exit0 endstart3.24编写计算100个16位正整数之和的程序。如果和不超过16位字的范围(65535),则保存其和到wordsum,如超过则显示‘overflow’。答: ;数据段count equ100parray dwcountdup(?) ;假设有100个数据wordsum dw0msg db‘overflow’,’$’ ;代码段 movcx,count movax,0 movbx,offsetparrayagain: addax,[bx] jncnext movdx,offsetmsg movah,9 int21h ;显示溢出信息 jmpdone ;然后,跳出循环体next: addbx,2 loopagain movwordsum,axdone: …3.25编程把—个16位无符号二进制数转换成为用8421BCD码表示的5位十进制数。转换算法可以是:用二进制数除以10000,商为“万位”,再用余数除以1000,得到“千位”;依次用余数除以l00、10和l,得到“百位”、“十位”和“个位”。;wjxt325.asm .modelsmall .stack256 .dataarray dw? ;源字数据dbcd db5dup(?) ;五位bcd结果,高对高低对低 .code .startup movdx,array ;取源数据(余数) movbx,10000 ;除数 movcx,10 ;除数系数 movsi,4 ;目的数据高位位移量again: movax,dx ;dx.ax中存放被除数 movdx,0 divbx ;除于bx,商ax,余数dx movdbcd[si],al ;商<10,存结果 pushdx ;暂存余数 movax,bx ;除数除于10 movdx,0 divcx ;dx.ax除于cx,商ax、余数0存在dx movbx,ax ;bx是除数 popdx decsi ;目的数据位移量减1 jnzagain movdbcd,dl ;存个位数(<10) .exit0 end3.26过程定义的一般格式是怎样的?子程序开始为什么常有PUSH指令?返回钱为什么常有POP指令?下面完成16位无符号数累加的子程序有什么不妥吗?若有,请改正。CarzyPROCPushaxXorax,axXorax,dxAgainaddax,[bx]Adcdx,0IncbxIncbxLoopagainRetENDPcrazy解: (1)汇编语言中,子程序要用一对过程伪指令PROC和ENDP声明,格式如下: 过程名 PROC[NEAR|FAR] …… ;过程体 过程名 ENDP (2)保护用到的寄存器内容,以便子程序返回时进行相应的恢复。 (3)改错: crazy proc pish bx push cx xor ax,ax xor dx,dx again:add a,[bx] adc dx,0 inc bx inc bx loop again pop cx pop bx3.27编写一个源程序,在键盘上按一个键,将从AL返回的ASCⅡ码值显示出来,如果按下ESC键则程序退出。解(不需调用HTOASC子程序):again: movah,1 int21h cmpal,1bh ;ESC的ASCII码是1bh jedone movdl,al movah,2 int21h ;是大写字母则转换为小写字母 jmpagaindone: …3.28请按如下说明编写子程序:;子程序功能:把用ASCⅡ码表示的两位十进制数转换为对应二进制数;入口参数:DH=十位数的ASCⅡ码,DL=个位数的ASCⅡ码;出口参数:AL=对应的二进制数解答:asctob proc pushcx anddh,0fh ;先转换十位数 shldh,1 ;十位数乘以10(采用移位指令) movch,dh shldh,1 shldh,1 adddh,ch anddl,0fh ;转换个位数 adddh,dl ;十位数加个位数 moval,dh ;设置出口参数 popcx retasctob endp3.29调用HTOASC子程序,显示一个字节的16进制数,后跟“H”的子程序。解:DIPASC proc ;入口参数:AL=要显示的一个16进制数 pushcx pushdx pushax movcl,4 ;转换高位 shral,cl callHTOASC movdl,al ;显示 movah,2 int21h popax ;转换低位 callHTOASC movdl,al ;显示 movah,2 int21h movdl,’H’ ;显示一个字母“H” movah,2 int21h popdx popcx retDIPASC endpHTOASC proc ;将AL低4位表达的一位16进制数转换为ASCII码 andal,0fh cmpal,9 jbehtoasc1 addal,37h ;是0AH~0FH,加37H转换为ASCII码 ret ;子程序返回htoasc1: addal,30h ;是0~9,加30H转换为ASCII码 ret ;子程序返回HTOASC endp3.30写一个子程序,根据入口参数AL=0、1、2,依次实现对大写字母转换成小写、小写转换成大写或大小字母互换。欲转换的字符串在string中,用0表示结束解:lucase proc pushbx movbx,offsetstring cmpal,0 jecase0 cmpal,1 jzcase1 cmpal,2 jzcase2 jmpdonecase0: cmpbyteptr[bx],0 jedone cmpbyteptr[bx],’A’ jbnext0 cmpbyteptr[bx],’Z’ janext0 addbyteptr[bx],20hnext0: incbx jmpcase0case1: cmpbyteptr[bx],0 jedone cmpbyteptr[bx],’a’ jbnext1 cmpbyteptr[bx],’z’ janext1 subbyteptr[bx],20hnext1: incbx jmpcase1case2: cmpbyteptr[bx],0 jedone cmpbyteptr[bx],’A’ jbnext2 cmpbyteptr[bx],’Z’ janext20 addbyteptr[bx],20h jmpnext2next20: cmpbyteptr[bx],’a’ jbnext2 cmpbyteptr[bx],’z’ janext2 subbyteptr[bx],20hnext2: incbx jmpcase2done: popbx retlucase endp3.31子程序的参数传递有哪些方法?请简单比较解: (1)用寄存器传递参数: 最简单和常用的参数传递方法是通过寄存器,只要把参数存于约定的寄存器中就可以了 由于通用寄存器个数有限,这种方法对少量数据可以直接传递数值,而对大量数据只能传递地址 采用寄存器传递参数,注意带有出口参数的寄存器不能保护和恢复,带有入口参数的寄存器可以保护、也可以不保护,但最好能够保持一致 (2)用共享变量传递参数 子程序和主程序使用同一个变量名存取数据就是利用共享变量(全局变量)进行参数传递 如果变量定义和使用不在同一个源程序中,需要利用PUBLIC、EXTREN声明 如果主程序还要利用原来的变量值,则需要保护和恢复 利用共享变量传递参数,子程序的通用性较差,但特别适合在多个程序段间、尤其在不同的程序模块间传递数据 (3)用堆栈传递参数 参数传递还可以通过堆栈这个临时存储区。主程序将入口参数压入堆栈,子程序从堆栈中取出参数;子程序将出口参数压入堆栈,主程序弹出堆栈取得它们 采用堆栈传递参数是程式化的,它是编译程序处理参数传递、以及汇编语言与高级语言混合编程时的常规方法3.32采用堆栈传递参数的一般方法是什么?为什么应该特别注意堆栈平衡问题。解: 方法:主程序将入口参数压入堆栈,子程序从堆栈中取出参数;子程序将出口参数压入堆栈,主程序弹出堆栈取得它们 注意:压栈与弹栈必须要一一对应。3.33编写一个求32位数据补码的子程序,通过寄存器传递入口参数解:方法1:neg32 proc ;入口参数:DX.AX=32位有符号数 negax ;实现0-DX.AX功能 negdx sbbdx,0 ;这条指令也可以用decdx代替 retneg32 endp ;出口参数:DX.AX=32位有符号数的补码方法2:neg32 proc ;入口参数:DX.AX=32位有符号数 notax ;实现DX.AX求反加1 notdx addax,1 adcdx,0 retneg32 endp ;出口参数:DX.AX=32位有符号数的补码3.34编写一个计算字节校验的子程序。所谓“校验和”是指不计进位的累加,常用语建厂信息的正确性。主程序提供入口参数,有数据个数和数据缓冲区的首地址。子程序回送求和结果这个出口参数。传递参数方法自定。解: ;数据段array db12h,25h,0f0h,0a3h,3,68h,71h,0cah,0ffh,90h ;数组count equ$-array ;数组元素个数result db? ;校验和 ;代码段 movbx,offsetarray ;BX←数组的偏移地址 movcx,count ;CX←数组的元素个数 callchecksum ;调用求和过程 movresult,al ;处理出口参数 movax,4c00h int21h ;计算字节校验和的通用过程 ;入口参数:DS:BX=数组的段地址:偏移地址,CX=元素个数 ;出口参数:AL=校验和 ;说明:除AX/BX/CX外,不影响其他寄存器checksum proc xoral,al ;累加器清0sum: addal,[bx] ;求和 incbx ;指向下一个字节 loopsum retchecksum endp end3.35编写3个子程序,把一个16位二进制数用4为16进制数在屏幕上显示出来,分别运用如下3中参数传递方法,并配合3个主程序验证它。(1)采用AX寄存器传递这个16位二进制数。(2)采用temp变量传递这个16位二进制数。(3)采用堆栈方法传递这个16位二进制数。解:⑴ .modelsmall .stack .datawdata dw34abh .code .startup movax,wdata calldispa .exit0 ;dispa proc pushcx pushdx movcl,4 movdl,ah shrdl,cl calldldisp movdl,ah anddl,0fh calldldisp movdl,al shrdl,cl calldldisp movdl,al anddl,0fh calldldisp popdx popcx retdispa endp ;dldisp proc pushax ordl,30h cmpdl,39h jbedldisp1 adddl,7dldisp1: movah,2 int21h popax retdldisp endp end⑵ .modelsmall .stack .datawdata dw34abhwordtemp dw? .code .startup movax,wdata movwordtemp,ax calldispa .exit0 ;dispa proc pushcx pushdx movcl,4 movdl,byteptrwordtemp+1 shrdl,cl calldldisp movdl,byteptrwordtemp+1 anddl,0fh calldldisp movdl,byteptrwordtemp shrdl,cl calldldisp movdl,byteptrwordtemp anddl,0fh calldldisp popdx popcx retdispa endp ;dldisp proc pushax ordl,30h cmpdl,39h jbedldisp1 adddl,7dldisp1: movah,2 int21h popax retdldisp endp end⑶ .modelsmall .stack .datawdata dw34abh .code .startup pushwdata calldispa popax ;addsp,2 .exit0 ;dispa proc pushbp movbp,sp pushax pushcx pushdx movax,[bp+4] movcl,4 movdl,ah shrdl,cl calldldisp movdl,ah anddl,0fh calldldisp movdl,al shrdl,cl calldldisp movdl,al anddl,0fh calldldisp popdx popcx popax popbp retdispa endp ;dldisp proc pushax ordl,30h cmpdl,39h jbedldisp1 adddl,7dldisp1: movah,2 int21h popax retdldisp endp end3.36什么情况需要使用PUBLIC和EXTERN伪指令?请将题3.20的子程序全部用于寄存器传递参数,写成子程序模块。解:如果利用共享变量传递函数,且变量定义和使用不在同一个源程序中,需要利用PUBLIC、EXTERN声明。3.37宏是如何定义、调用和展开的?解:(1)宏定义由一对宏汇编伪指令MACRO和ENDM来完成,格式如下: 宏名 MACRO[形参表] …… ;宏定义体 ENDM宏定义之后就可以使用它,即宏调用: 宏名[实参表](2)宏调用的格式同一般指令一样:在使用宏指令的位置写下宏名,后跟实体参数;如果有多个参数,应按形参顺序填入实参,也用逗号分
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 顺应论视角下英语专业研究生英汉语码转换现象研究
- 2025年压缩式垃圾车项目合作计划书
- 培训老师会给
- 中职学生健康教育
- 高中生多元智能与英语词汇学习策略的相关性研究
- 金属氧化物基电催化剂的制备及其电解水性能的研究
- 铁基催化剂制备及其催化废塑料裂解制碳纳米管性能研究
- 【+初中语文+】第7课《大雁归来》课件+统编版语文八年级下册
- 《高考备考指南 数学 》课件-【高考专题突破(四)】-高考中立体几何问题的热点题型
- 探究水沸腾前后温度变化的特点 实验报告
- 剪辑拍摄培训课件
- 小学科技小制作知识讲座
- 电子商务仓库管理培训课程培训课件
- 阿瑞匹坦注射液-临床用药解读
- 民事案例实例分析课件
- 传染病预检分诊流程
- 学术规范和论文写作 课件 第9章 学术规范与学术失范
- 小学篮球社团简介
- 股权投资的基本概念与原理
- 数学五下《你知道吗阿基米德巧辨皇冠真假》课件西南师大版-五年级数学课件
- 自检记录表钢筋
评论
0/150
提交评论