这个sub三目运算符判断三个值是16位的,那这怎么判断cf sf of呢?

> 问题详情
试分别写出下列各式中的16位运算结果和标志OF、SF、ZF、AF、PF、CF的状态。
悬赏:0&答案豆
提问人:匿名网友
发布时间:
试分别写出下列各式中的16位运算结果和标志OF、SF、ZF、AF、PF、CF的状态。
您可能感兴趣的试题
1已知下列是486在16位空间中使用的指令,指出其中操作数的寻址方式。2已知下列是486在16位空间中使用的指令,请指出其中存储器操作数的逻辑地址(段地址:有效地址)。3486在16位和32位空间中各有哪些寻址方式?这些寻址方式有哪些共同点和不同点?使用时应该注意一些什么?4指出下列指令中各操作数的大小。
我有更好的答案
请先输入下方的验证码查看最佳答案
图形验证:
验证码提交中……
找答案会员
享三项特权
找答案会员
享三项特权
找答案会员
享三项特权
选择支付方式:
支付宝付款
郑重提醒:支付后,系统自动为您完成注册
请使用微信扫码支付(元)
支付后,系统自动为您完成注册
遇到问题请联系在线客服QQ:
恭喜你被选中为
扫一扫-免费查看答案!
请您不要关闭此页面,支付完成后点击支付完成按钮
遇到问题请联系在线客服QQ:
恭喜您!升级VIP会员成功
提示:请截图保存您的账号信息,以方便日后登录使用。
常用邮箱:
用于找回密码
确认密码:Access denied | jocent.me used Cloudflare to restrict access
Please enable cookies.
What happened?
The owner of this website (jocent.me) has banned your access based on your browser's signature (3f37-ua98).3被浏览101分享邀请回答0添加评论分享收藏感谢收起汇编语言程序设计(第四版)第1~4章【课后答案】-海文库
全站搜索:
您现在的位置:&>&&>&理学
汇编语言程序设计(第四版)第1~4章【课后答案】
汇编语言程序设计
第四版【课后习题答案】第1章 汇编语言基础知识〔习题1.1〕简述计算机系统的硬件组成及各部分作用。〔解答〕CPU:包括运算器、控制器和寄存器组。运算器执行所有的算术和逻辑运算;控制器负责把指指令逐条从存储器中取出,经译码分析后向机器发出各种控制命令,并正确完成程序所要求的功能;寄存器组为处理单元提供所需要的数据。存储器:是计算机的记忆部件,它用来存放程序以及程序中所涉及的数据。 外部设备:实现人机交换和机间的通信。〔习题1.2〕明确下列概念或符号: 主存和辅存,RAM和ROM,存储器地址和I/O端口,KB、MB、GB和TB。〔解答〕主存又称内存是主存储器的简称,主存储器存放当前正在执行的程序和使用的数据,CPU可以直接存取,它由半导体存储器芯片构成其成本高、容量小、但速度快。辅存是辅助存储器的简称,辅存可用来长期保存大量程序和数据,CPU需要通过I/O接口访问,它由磁盘或光盘构成,其成本低、容量大,但速度慢。RAM是随机存取存储器的英语简写,由于CPU可以从RAM读信息,也可以向RAM写入信息,所以RAM也被称为读写存储器,RAM型半导体存储器可以按地址随机读写,但这类存储器在断电后不能保存信息;而ROM中的信息只能被读出,不能被修改,ROM型半导体通常只能被读出,但这类存储器断电 - 1 -
后能保存信息。存储器由大量存储单元组成。为了区别每个单元,我们将它们编号,于是,每个存储单元就有了一个存储地址,I/O接口是由一组寄存器组成,为了区别它们,各个寄存器进行了编号,形成I/O地址,通常称做I/O端口。KB是千字节、MB是兆字节、GB是吉字节和TB是太字节,它们都是表示存储器存储单元的单位。〔习题1.3〕什么是汇编语言源程序、汇编程序、目标程序?〔解答〕用汇编语言书写的程序就称为汇编语言源程序;完成汇编工作的程序就是汇编程序;由汇编程序编译通过的程序就是目标程序。〔习题1.4〕汇编语言与高级语言相比有什么优缺点?〔解答〕汇编语言与高级语言相比的优点:由于汇编语言本质就是机器语言,它可以直接地、有效地控制计算机硬件,因而容易产生运行速度快,指令序列短小的高效目标程序,可以直接控制计算机硬件部件,可以编写在“时间”和“空间”两方面最有效的程序。汇编语言与高级语言相比的缺点:由于与处理器密切相关导致通用性差、可移植性差,汇编语言功能有限,又涉及寄存器、主存单元等硬件细节,编写汇编语言比较繁琐,调试起来也比较困难,编译程序产生的目标程序往往比较庞大、程序难以优化,运行速度慢。〔习题1.5〕将下列十六进制数转换为二进制和十进制表示(1)FFH
(4)EFH(5)2EH
(8)ABH〔解答〕(1)FFH
255D(2)0H
0D(3)5EH
94D(4)EFH239D(5)2EH
46D(6)10H
16D(7)1FH
31D(8)ABH
171D〔习题1.6〕将下列十进制数转换为BCD码表示(1)12
(4)127(5)128
(7)1234(8)2458〔解答〕(1)12
0100(8)2458
1000〔习题1.7〕将下列BCD码转换为十进制数(1)
(3)(5)
(7)〔解答〕(1)91(2)89(3)36(4)90- 4 - (4)8)
(5)08(6)97(7)81(8)02〔习题1.8〕将下列十进制数分别用8位二进制数的原码、反码和补码表示(1)0
(3)127(4)-57(5)126
(7)-128(8)68〔解答〕(1)0
111110(6)-126
000010(7)-128
〔习题1.9〕完成下列二进制数的运算(1)
(4)÷1001- 5 -
(5)1011 ∧1001
(6)1011 ∨1001 (7)~1011
(8)1011 ? 1001〔解答〕(1)=10100(2)=0010(3)=1100011(4)01=10100,余数 1000(5)1011 ∧ (6)1011 ∨(7)~(8) 10(?代表异或)〔习题1.10〕数码0~9、大写字母A~Z、小写字母a~z对应的ASCII码分别是多少?ASCII码为0dh、0ah对应的是什么字符?〔解答〕数码0~9:30H~39H大写字母A~Z:41H~5AH小写字母a~z:61H~7AHASCII码为0dh、0ah分别对应回车和换行控制字符。〔习题1.11〕计算机中有一个“”编码,如果把它认为是无符号数,它是十进制什么数?如果认为它是BCD码,则表示什么数?又如果它是某个ASCII码,则代表哪个字符?〔解答〕- 6 -
十进制无符号数:B=61H=97BCD码:61ASCII码:a〔习题1.12〕简述Intel 80x86系列微处理器在指令集方面的发展。〔解答〕1978年Intel,正式推出了16位8086CPU,1979年Intel推出了准16位微处理器8088,随后,Intel推出了,指令系统比8086指令系统新增了若干条实用的指令,涉及堆栈操作、移位指令、过程指令和边界检测及乘法指令,1982年Intel推出80286 CPU, 80286指令系统包括全部80186指令及新增的保护指令15条,其中有些保护方式在实方式下也可以使用,1985年,Intel80x86推出微处理器地进入第三代80386 CPU, 80386指令系统在兼容原来16位指令系统的基础上,全面升级为32位,还新增了有关位操作、条件设置指令以及控制、调试和测试寄存器的传送指令等,1989年,Intel推出了80486CPU,80486将浮点处理单元FPU集成进来,还采用了精简指令集计算机技术RISC和指令流水线方式,还新增了用于多处理器和内部Cache操作的6条指令,1993年Intel制成了俗称586的微处理器,取名Pentium。Pentium仍为32位结构,地址总线为32位,对常用的简单指令用硬件实现,重新设计指令的微代码等,Pentium新增了一条8字节比较交换指令和一条处理器识别指令,以及4条系统专用指令,1996年推出了MMX Pentium,新增了57条多媒休指令,1995年Intel推出Pentium Pro新增了3条指令,1999年推出了PentiumⅢ新增了70条SSE指令,2000年推出的Pentium4新增了76条SSE2指令- 7 -
〔习题1.13〕什么是DOS和ROM-BIOS?〔解答〕DOS是Diskette Operating system的缩写,意思是磁盘操作系统,DOS主要是面向磁盘的系统软件,说得简单些,就是人与机器的一座桥梁,是罩在机器硬件外面的一层“外壳”,是年的个人电脑上使用的一种主要的操作系统。BIOS(Basic Input/Output System)即基本输入输出系统,通常是固化在只读存储器(ROM)中,所以又称为ROM-BIOS。它直接对计算机系统中的输入、输出设备进行设备级、硬件级的控制,是连接软件程序和硬件设备之间的枢纽。ROM-BIOS是计算机系统中用来提供最低级、最直接的硬件控制的程序。〔习题1.14〕简述PC机最低1MB主存空间的使用情况。〔解答〕(1)基本RAM区(00000H―9FFFFH)该区共640KB,由DOS进行管理。在这个区域中操作系统要占用掉一部分低地址空间,其它则向用户程序开放。(2)保留区RAM(A0000H--BFFFFFH)该区为系统安排的“显示缓冲存储区”,共126KB,是显卡上的芯片提供支持,用于存放屏幕显示信息。但这部分地址空间实际上并没有全部使用。(3)扩展区ROM(C0000H--DFFFFH)该区128KB,由接口卡上的芯片提供支持,用于为系统不直接支持的外设安排设备驱动程序。用户固化的程序就可[安排在这一段,系统的会对它进行确认和连接。(4)系统区ROM(E0000H--FFFFFH)该区共128KB,由系统占用,它主要提供ROM--BIOS程序,基本输入输出程序BIOS,是操作系统的重要组成 - 8 -
部分,主要用来驱动输入输出设备,也负责系统的上电检测,磁盘引导等初始化操作,在ROM--BIOS中还有CMOS微机设置程序以及使用的字符图符信息等内容。〔习题1.15〕罗列8086CPU的8个8位和16位通用寄存器,并说明各自的作用。〔解答〕(1)数据寄存器:AX称为累加器,使用频度最高,用于算术、逻辑运算以及与外设传送信息等;BX称为基址寄存器,常用做存放存储器地址;CX称为计数器,作为循环和串操作等指令中的隐含计数器;DX称为数据寄存器,常用来存放双字长数据的高16位,或存放外设端口地址。(2)指针及变址寄存器包括SI,DI,BP,S P,四个寄存器,常用于存储器寻址时提供地址。SI是源变址寄存器,DI是目的变址寄存器,一般与DS联用确定数据段和附加段中某一存储单元地址,在串指令中,SI与DS联用、DI和ES联用,分别寻址数据段和附加段;同时,在串指令中,SI和DI还都具有自动增量或减量的功能。S P,为堆栈指针寄存器,指示栈顶的偏移地址;BP为基地址指针寄存器,表示堆栈段中的基地址。S P与BP寄存器均可与SS段寄存器联合使用以确定堆栈段中的存储单元地址。〔习题1.16〕什么是标志,它有什么用途?状态标志和控制标志有什么区别?画出标志寄存器FLAGS,说明各个标志的位置和含义。〔解答〕标志用于反映指令执行结果或控制指令执行形式。它是汇编语言程序设计中必须特别注意的一个方面,状态用来记录运行的结果的状态信息,许多指令的执 - 9 -
行都将相应地设置它,控制标志位可由程序根据需要用指令设置,用来控制处理器执行指令的方式。
CF是进位标志;ZF 是零标志;SF是符号标志;PF奇偶标志;OF溢出标志;AF辅助进位标志;DF方向标志;IF中断允许标志;TF陷阱标志。〔习题1.17〕举例说明CF和OF标志的差异。〔解答〕溢出标志OF和进位标志CF是两个意义不同的标志。进位标志表示无符号数运算结果是否超出范围,运算结果仍然正确;溢出标志表示有符号数运算结果是否超出范围,运算结果已经不正确。例1:3AH + 7CH=B6H无符号数运算:58+124=182,范围内,无进位有符号数运算: 58+124=182 ,范围外,有溢出例2:AAH + 7CH=(1)26H无符号数运算:170+124=294,范围外,有进位有符号数运算:-86+124=28 ,范围内,无溢出〔习题1.18〕字和双字在存储器中如何存放,什么是“小端方式”?对字和双字存储单元,什么是它们的对齐地址?为什么要对齐地址?〔解答〕字或双字在存储器中占相邻的2个或4个存储单元;存放时,低字节存入低地址,高字节存入高地址;字或双字单元的地址用它的低地址来表示。80x86处理器采用的这种“低对低,高对高”的存储形式,被称为“小端方式”;将字 - 10 -
单元安排在偶地址,双字节单元安排在模4地址,被称为“地址对齐方式”因为对于不对齐地址的数据,处理器访问时,需要额外的访问时间,所以通常应该将数据的地址对齐,以取得较高的存取速度。〔习题1.19〕什么是8086中的逻辑地址和物理地址?逻辑地址如何转换成物理地址?请将如下逻辑地址用物理地址表达:(1)FFFFh:0
(2)40h:17h
(4)B821h:4567h 〔解答〕在8086处理器中,对应每个物理存储单元都有一个唯一的20位编号,就是物理地址,从00000H~FFFFFH。在8086内部和用户编程时,采用的段基地址 : 段内偏移地址形式称为逻辑地址。将逻辑地址中的段地址左移二进制4位(对应16进制是一位,即乘以16),加上偏移地址就得到20位物理地址如下逻辑地址用物理地址表达:(1)FFFFh:0=FFFF0H(2)40h:17h=00417H(3)h=24500H(4)B821h:4567h=BC777H
(不要算错)〔习题1.20〕8086有哪4种逻辑段,各种逻辑段分别是什么用途?〔解答〕代码段(Code Segment)用来存放程序的指令序列。处理器利用CS : IP取得下一条要执行的指令。- 11 -
堆栈段(Stack Segment)确定堆栈所在的主存区域。处理器利用SS : SP操作堆栈中的数据。数据段(Data Segment)存放当前运行程序所用的数据。处理器利用DS : EA存取数据段中的数据。附加段(Extra Segment)是附加的数据段,也用于数据的保存。处理器利用ES : EA存取数据段中的数据〔习题1.21〕数据的默认段是哪个,是否允许其他段存放数据?如果允许,如何实现,有什么要求?〔解答〕数据的默认段是安排在数据段,也经常安排在附加段,尤其是串操作的目的区必须是附加段,允许其它段存放数据,数据的存放比较灵活的,实际上可以存放在任何一种逻辑段中,这时,只要明确指明是哪个逻辑段就可以了。〔习题1.22〕什么是操作码、操作数和寻址方式?有哪三种给出操作数的方法?〔解答〕操作码说明计算机要执行哪种操作,它是指令中不可缺少的组成部分,操作数是指令执行的参与者,也是各种操作的对象,我们把寻找数的方式叫做操作数的寻址方式。给出操作数的三种方法是直接给出,间接给出,隐藏操作数方式给出。〔习题1.23〕什么是有效地址EA?8086的操作数如果在主存中,有哪些寻址方式可以存取它?〔解答〕- 12 -
DS存放数据段的段地址,存储器中操作数的偏移地址则由各种主存方式得到,称之为有效地址EA。8086的操作数如果在主存中,可以存取它的寻址方式有直接寻址方式、寄存器间接寻址方式、寄存器相对寻址方式、基址变址寻址方式、相对基址变址寻址方式。〔习题1.24〕说明下列指令中源操作数的寻址方式?如果BX=2000H,DI=40H,给出DX的值或有效地址EA的值。(1) mov dx,[1234h](2) mov dx,1234h(3) mov dx,bx(4) mov dx,[bx](5) mov dx,[bx+1234h](6) mov dx,[bx+di](7) mov dx,[bx+di+1234h]〔解答〕(1)直接寻址,EA=1234H(2)立即数寻址,DX=1234H(3)寄存器寻址,DX=2000H(4)间接寻址,EA=2000H(5)相对寻址,EA=3234H(6)基址变址寻址,EA=2040H(7)相对基址变址寻址,EA=3274H第2章 8086的指令系统- 13 -
〔习题2.1〕已知DS=2000H、BX=0100H、SI=0002H,存储单元[20100H]~[20103H]依次存放12 34 56 78H,[21200H]~[21203H]依次存放2A 4C B7 65H,说明下列每条指令执行完后AX寄存器的内容。(1) mov ax,1200h(2) mov ax,bx(3) mov ax,[1200h](4) mov ax,[bx](5) mov ax,[bx+1100h](6) mov ax,[bx+si](7) mov ax,[bx][si+1100h]〔解答〕(1)AX=1200H(2)AX=0100H(3)AX=4C2AH偏移地址=bx=0100h(4)AX=3412H偏移地址=bx=0100h(5)AX=4C2AH偏移地址=bx+h(6)AX=7856H偏移地址=bx+si=h=0102h- 14 -
(7)AX=65B7H偏移地址=bx+si+h+h=1202h
〔习题2.2〕指出下列指令的错误(1) mov cx,dl(2) mov ip,ax(3) mov es,1234h(4) mov es,ds(5) mov al,300(6) mov [sp],ax(7) mov ax,bx+di(8) mov 20h,ah〔解答〕(1)两操作数类型不匹配(2)IP指令指针禁止用户访问(3)立即数不允许传给段寄存器(4)段寄存器之间不允许传送(5)两操作数类型不匹配- 15 -
(6)目的操作数应为[ SI ](7)源操作数应为 [BX+DI](8)立即数不能作目的操作数〔习题2.3〕已知数字0 ~ 9对应的格雷码依次为:18H、34H、05H、06H、09H、0AH、0CH、11H、12H、14H,它存在于以table为首地址(设为200H)的连续区域中。请为如下程序段的每条指令加上注释,说明每条指令的功能和执行结果。lea bx,tablemov al,8xlat〔解答〕lea bx,table
;获取table的首地址,BX=200Hmov al,8
;传送欲转换的数字,AL=8xlat
;转换为格雷码,AL=12H
P35〔习题2.4〕什么是堆栈,它的工作原则是什么,它的基本操作有哪两个,对应哪两种指令?〔解答〕- 16 -
堆栈是一种按“先进后出”原则存取数据的存储区域,位于堆栈段中,使用SS段寄存器记录其段地址;它的工作原则是先进后出;堆栈的两种基本操作是压栈和出栈,对应的指令是PUSH和POP。〔习题2.5〕已知SS = 2200H、SP = 00B0H,画图说明执行下面指令序列时,堆栈区和SP的内容如何变化?mov ax,8057hpush axmov ax,0f79hpush axpop bxpop [bx]〔解答〕mov ax,8057hpush axmov ax,0f79hpush axpobx=0f79hpop [bx]DS:[0f79h]=8057h- 17 -
〔习题2.6〕给出下列各条指令执行后AL值,以及CF、ZF、SF、OF和PF的状态:mov al,89hadd al,aladd al,9dhcmp al,0bchsub al,aldec alinc al〔解答〕
mov al,89 AL=89h
PF add al, AL=12h
add al,9dh; +
cmp al,0bch; -*
sub al,al; AL=0afh
1 ; AL=0afh
dec a AL=0ffh
inc al AL=00h
〔习题2.7〕设X、Y、Z均为双字数据,分别存放在地址为X、X+2;Y、Y+2;Z、Z+2的存储单元中,它们的运算结果存入W单元。阅读如下程序段,给出运算公式。mov ax,Xmov dx,X+2
add ax,Yadc dx,Y+2
add ax,24adc dx,0
sub ax,Zsbb dx,Z+2
mov W,axmov W+2,dx〔解答〕W=X+Y+24-Z〔习题2.8〕请分别用一条汇编语言指令完成如下功能:(1)把BX寄存器和DX寄存器的内容相加,结果存入DX寄存器。(2)用寄存器BX和SI的基址变址寻址方式把存储器的一个字节与AL寄存器的内容相加,并把结果送到AL中。(3)用BX和位移量0B2H的寄存器相对寻址方式把存储器中的一个字和CX寄存器的内容相加,并把结果送回存储器中。(4)用位移量为0520H的直接寻址方式把存储器中的一个字与数3412H相加,并把结果送回该存储单元中。(5)把数0A0H与AL寄存器的内容相加,并把结果送回AL中。
〔解答〕(1)ADD DX,BX(2)ADD AL,[BX+SI](3)ADD [BX+0B2H],CX(4)ADD WORD PTR [0520H],3412H(5)ADD AL,0A0H〔习题2.9〕设X、Y、Z、V均为16位带符号数,分别装在X、Y、Z、V存储单元中,阅读如下程序段,得出它的运算公式,并说明运算结果存于何处。mov ax,Xax=Ximul YDX.AX=X*Y
mov cx,cx=X*Y的低16位mox bx,bx=X*Y的高16位
mov ax,Zax=Zcwdadd cx,cx=Z的低16位+X*Y的低16位adc bx,bx=Z的高16位+X*Y的高16位+低位进位- 22 -
sub cx,540cx=Z的低16位+X*Y的低16位-540sbb bx,0bx=Z的高16位+X*Y的高16位+低位进位-低位借位
mov ax,Vax=Vcwdsub ax,ax=V的低16位(-Z的低16位+X*Y的低16位-540)
sbb dx,dx=V的高16位-(Z的高16位+X*Y的高16位+低位进位-低位借位)-低位借位
idiv X ;/X〔解答〕[V-(X*Y+Z-540)]/XAX存商,DX存余数〔习题2.10〕指出下列指令的错误:(1) xchg [si],30h(2) pop cs- 23 -
(3) sub [si],[di](4) push ah(5) adc ax,ds(6) add [si],80h(7) in al,3fch(8) out dx,ah〔解答〕(1)xchg的操作数不能是立即数(2)不应对CS直接赋值(3)两个操作数不能都是存储单元(4)堆栈的操作数不能是字节量(5)adc的操作数不能是段寄存器(6)没有确定是字节还是字操作(7)in不支持超过FFH的直接寻址(8)out只能以AL/AX为源操作数〔习题2.11〕给出下列各条指令执行后的结果,以及状态标志CF、OF、SF、ZF、PF的状态。mov ax,1470h- 24 -
and ax,axor ax,axxor ax,axnot axtest ax,0f0f0h〔解答〕mov ax,1470h
;AX=1470H CF
PFand ax,ax
;AX=1470H 0
;AX=1470H 0
0xor ax,ax
;AX=0000H 0
;AX=FFFFH 0
1test ax,0f0f0h
;AX=FFFFH 0
1注意:MOV和NOT指令不影响标志位;其他逻辑指令使CF=OF=0,根据结果影响其他标志位。- 25 -
〔习题2.12〕假设例题2.34的程序段中,AX = 08H,BX = 10H,请说明每条指令执行后的结果和各个标志位的状态。〔解答〕指令 执行结果
CF OF SF ZF PFmov si, SI=AX=0008H
-shl si,1 SI=2*AX=0010H
0add si, SI=3*AX=0018H
mov dx, DX=BX=0010H
mov cl,03 CL=03H
1shl dx, DX=8*BX=0080H
sub dx, DX=7*BX=0070H
0add dx, DX=7*BX+3*AX=0088H
1注意:逻辑左移N次相当于无符号整数乘以2的N次方,逻辑右移N次相当于无符号整数除以2的N次方。移位指令根据移位的数据设置CF,根据移位后的结果影响SF,ZF,PF。在进行一位移位时,根据最高符号位是否改变设置OF,如改变则OF=1。另外,程序注释用“u”表示标志无定义(不确定),“-”表示无影响。〔习题2.13〕编写程序段完成如下要求:(1)用位操作指令实现AL(无符号数)乘以10- 26 -
(2)用逻辑运算指令实现数字0 ~ 9的ASCII码与非压缩BCD码的互相转换(3)把DX.AX中的双字右移4位〔解答〕(1) ;不考虑进位mov bl,almov cl,3shl al,*8add al,shl bl,1add al,bl;考虑进位xor ah,ahmov bx,axmov cl,3shl ax,cladd ax,shl bx,1add ax,bx(2)数字0~9的ASCII码是:30h~39h- 27 -
非压缩BCD码的0~9是:00h~09h方法一:and al,0实现ASCII到非压缩BCD码的转换or al,30实现非压缩BCD码到ASCII的转换方法二:xor al,30h
;求反D5D4位,其他不变;即高4位为3,则变为0;高4位为0,则变为3(3)
mov cl,4again:
shr dx,1实现逻辑右移;采用“sar dx,1”,则实现算术右移
rcr ax,1dec cljnz again〔习题2.14〕已知AL = F7H(表示有符号数-9),分别编写用SAR和IDIV指令实现的除以2的程序段,并说明各自执行后,所得的商是什么?〔解答〕(1)用sar编写mov al,0f7 -9送AL - 28 -
sar al,1 结果:AL=B=0FBH
即-5(2)用idiv编写mov al,0f7 -9送alcb 字节符号扩展位字mov bl,2 注意除数不可为立即数id 结果:商为al=fch
(-4); 余数:ah=ffh (-1)结论:符号数的除法用idiv 准确。
〔习题2.15〕指令指针IP是通用寄存器还是专用寄存器?有指令能够直接它赋值吗?哪类指令的执行会改变它的值?〔解答〕指令指针IP不是通用寄存器,不可直接赋值,属于专用寄存器。有且仅有循环、转移、子程序调用和返回、中断类等指令可以改变它的值。〔习题2.16〕控制转移类指令中有哪三种寻址方式?〔解答〕控制转移类指令的寻址方式:相对寻址、直接寻址方式和间接寻址方式(又可以分成寄存器和存储器间接寻址)。- 29 -
〔习题2.17〕什么是短转移short jump、近转移near jump和远转移far jump?什么是段内转移和段间转移?8086有哪些指令可以实现段间转移?〔解答〕短转移:指段内-128~127之间的转移,位移量用一个字节表示近转移:指段内±32K之间的转移,位移量用一个字表示远转移:指段间1MB范围的转移段内转移:指在同一个代码段内的转移,可以是短转移或者近转移段间转移:指转移到另外一个代码段,就是远转移CPU的JMP、CALL和INT n指令可以实现段间转移〔习题2.18〕8086的条件转移指令的转移范围有多大?实际编程时,你如何处理超出范围的条件转移?〔解答〕8086的条件转移的转移范围:在当前指令地址的 +127~-128之内。 如条件转移的转移范围超出此范围,可在此范围内安排一条无条件转移,再转移到范围外的目标地址。〔习题2.19〕假设DS=2000H,BX=1256H,SI=528FH,位移量TABLE=20A1H,[232F7H]=3280H,[264E5H]=2450H,试问执行下列段内间接寻址的转移指令后,转移的有效地址是什么?(1) JMP BX- 30 -
(2) JMP TABLE[BX](3) JMP [BX][SI]〔解答〕(1)转移的有效地址EA= BX=1256H(2)转移的有效地址EA= [DS:20A1H+1256H]=[232F7]=3280H(3)转移的有效地址EA= [DS:FH]=264E5H=2450H 〔习题2.20〕判断下列程序段跳转的条件(1) xor ax,1e1ehje equal(2)test al,bjnz there(3)cmp cx,64hjb there〔解答〕(1)AX=1e1eh(异或后为0)(2)AL的D0或D7至少有一位为1(3)CX(无符号数)< 64h〔习题2.21〕设置CX = 0,则LOOP指令将循环多少次?例如:
mov cx,0delay:
loop delay〔解答〕216次。〔习题2.22〕假设AX和SI存放的是有符号数,DX和DI存放的是无符号数,请用比较指令和条件转移指令实现以下判断:(1)若DX & DI,转到above执行;(2)若AX & SI,转到greater执行;(3)若CX = 0,转到zero执行;(4)若AX-SI产生溢出,转到overflow执行;(5)若SI≤AX,转到less_eq执行;(6)若DI≤DX,转到below_eq执行。〔解答〕(1)若DX & DI,转到above执行cmp dx,dija above
;=jnbe above(2)若AX & SI,转到greater执行cmp ax,si- 32 -
jg greater
;=jnle greater(3)若CX = 0,转到zero执行cmp cx,0jz= jcxz zero(4)若AX-SI产生溢出,转到overflow执行;cmp ax,sijo overflow(5)若SI≤AX,转到less_eq执行;cmp si, cmp ax,sijle less_ jge less_eq(6)若DI≤DX,转到below_eq执行。cmp di, cmp dx,dijbe below_ jae below_eq〔习题2.23〕有一个首地址为array的20个字的数组,说明下列程序段的功能。mov cx,20mov ax,0mov si,ax- 33 -
add ax,array[si]add si,2loop sum_loopmov total,ax〔解答〕将首地址为array得20个字的数组求和,并将结果存入 total 单元中。 〔习题2.24〕按照下列要求,编写相应的程序段:(1)起始地址为string的主存单元中存放有一个字符串(长度大于6),把该字符串中的第1个和第6个字符(字节量)传送给DX寄存器。(2)从主存buffer开始的4个字节中保存了4个非压缩BCD码,现按低(高)地址对低(高)位的原则,将它们合并到DX中。(3)编写一个程序段,在DX高4位全为0时,使AX = 0;否则使AX = -1。(4)有两个64位数值,按“小端方式”存放在两个缓冲区buffer1和buffer2中,编写程序段完成buffer1-buffer2功能。(5)假设从B800h : 0开始存放有100个16位无符号数,编程求它们的和,并把32位的和保存在DX.AX中。(6)已知字符串string包含有32KB内容,将其中的’$’符号替换成空格。- 34 -
(7)有一个100个字节元素的数组,其首地址为array,将每个元素减1(不考虑溢出)存于原处。(8)统计以 ’$’ 结尾的字符串srting的字符个数。〔解答〕(1)解答:mov si,0mov dl,string[si]
;第1个字符送dl寄存器:mov dl,stirng[0]
mov si,5mov dh,string[si]
;第6个字符送dh寄存器:mov dl,stirng[5](2)解答:xor si,si
;si清零mov al,buffer[si]
;第一字节inc simov ah,buffer[si]
;第二字节mov cl,4shl ah,cl
;BCD码移到高半字节or al,ah
;组合成压缩BCD码mov dl,al
;存入dl寄..- 35 -
inc simov al,buffer[si]
;第三字节inc simov ah,buffer[si]
;第四字节mov cl,4shl ah,cl
;BCD码移到高半字节
;组合成压缩BCD码
;存入dh寄..(3)解答:test dx,0f000 test dh,0f0hjz jnz nextmov ax,-1 mov ax,0jmp againnext:
mov ax,0 mov ax,0ffffhagain:
...(4)解答:mov ax, word ptr buffer1sub ax, word ptr buffer2
;先减低16位
mov dx, word ptr buffer1+2sbb dx, word ptr buffer2+2
;后减高16位,需减低16位的借位(5)解答:mov ax,0b800hmov ds,ax
;段地址xor si,si
;地址偏移量si=0xor dx,dx
;和的高字dx=0mov cx,99
;加的次数mov ax,[si]
;第一个数again:
;指向下一个字单元inc siadd ax,[si]
;加下一个数jnc
;无进位转inc dx
;有进位dx=dx+1noc:
;次数-1jnz cx,again
;非0继续加(6)解答1:不使用串操作指令(更好)- 37 -
mov si,offset stringmov cx,^15=8000hagain:
cmp byte ptr [si], ‘$’‘$’ =24h
jnz ne 不要采用 jz 进行分支mov byte ptr [si], ‘
’‘ ’=20h next:
inc siloop a dec cx; jnz again(6)解答2:使用串操作指令mov di,offset stringmov al,’$’mov cx,8000hcldagain:
scasbjnz nextmov byte ptr es : [di-1], ‘
loop again(7)解答1:mov si,offset arraymov cx,100again:
dec byte ptr [si]inc siloop again(7)解答2:xor si, si&--0mov cx,100 循环次数
dec array[si]inc siloop again(7)解答3:mov si,offset arraymov di,simov ax,ds- 39 -
mov es,axmov cx,100cldagain:
lodsbdec alstosbloop again(8)解答:xor si,si&--0coun:
cmp string[si],'$'je
doneinc sijmp coundone:
...〔习题2.25〕对下面要求,分别给出3种方法,每种方法只用一条指令。(1)使CF=0
(2)使AX=0
(3)同时使AX=0和CF=0〔解答〕(1)解答:- 40 -
clcand ax,axor ax,ax(2)解答:xor ax,axand ax,0mov ax,0(3)解答:and ax,0xor ax,axsub ax,ax〔习题2.26〕参照本习题的示意图,分析调用序列,画出每次调用及返回时的堆栈状态。其中CALL前是该指令所在的逻辑地址;另外,段内直接调用指令的机器代码的字节数为3,段间直接调用指令则为5个字节。〔解答〕主程序转子suba时段内调用:断点1为2000h:0400h+3,转子是只将IP压栈。suba转子subb时段间调用:断点2为2000h:0840h+5, 转子时须将cs段地址和IP压栈- 41 -
suba转子subc时段内调用:断点3为2000h:0c021h+3,转子是只将IP压栈。注:压栈时先修改sp再压入断点,弹栈时先弹出断点再修改sp。〔习题2.27〕已知AX 、BX存放的是4位压缩BCD表示的十进制数,请说明如下子程序的功能和出口参数。add al,bldaaxchg al,ahadc al,bhdaaxchg al,ahret〔解答〕压缩BCD码加法:AX←AX+BX出口参数:AX=BCD码和〔习题2.28〕AAD指令是用于除法指令之前,进行非压缩BCD码调整的。实际上,处理器的调整过程是:AL←AH×10+AL,AH←0。如果指令系统没有AAD指令,请用一个子程序完成这个调整工作。〔解答〕- 42 -
shl ah,1ah=2*a
(设原ah=a)mov dl,dl=2*amov cl,2设定移位次数shl ah,ah=8*aadd ah,ah=10*aadd al,al=10*a+alxor ah,清零ahint 3返回DOS注意: 入口:AX中存放有“和”(两非压缩BCD码)出口:AL中 已为调整后的二进制数〔习题2.29〕解释如下有关中断的概念:(1) 内部中断和外部中断(2) 单步中断和断点中断(3) 除法错中断和溢出中断(4) 中断向量号和中断向量表〔解答〕(1)内部中断是由于8086CPU内部执行程序引起的程序中断;外部中断是来自8086CPU之外的原因引起的程序中断;- 43 -
(2)单步中断是若单步标志TF为1,则在每条指令执行结束后产生的中断;断点中断是供调试程序使用的,它的中断类型号为3通常调试程序时,把程序按程序的任务分成几段,然后,每段设一个段点;(3)除法错中断是在执行除法指令时,若除数为0或商超过了寄存器所能表达的范围产生的中断;溢出中断是在执行溢出中断指令INTO时,若溢出标志OF为1时产生的中断;(4)中断向量号是 中断类型号;中断向量表是中断向量号与它所对应的中断服务程序起始地址的转换表。〔习题2.30〕试比较INT n和段间CALL指令、IRET和段间RET指令的功能。〔解答〕INT n 响应中断时,除象CALL保护断点外,还应保护FR;段间CALL指令用在主程序中实现子程序的调用。IRET 返回时,除象RET恢复断点外,还应恢复FR;子程序执行完成后,应返回主程序中继续执行,这一功能由RET指令完成。第3章 汇编语言程序格式〔习题3.1〕伪指令语句与硬指令语句的本质区别是什么?伪指令有什么主要作用?〔解答〕伪指令语句与硬指令语句的本质区别是能不能产生CPU动作;- 44 -
伪指令的作用是完成对如存储模式、主存变量、子程序、宏及段定义等很多不产生CPU动作的说明,并在程序执行前由汇编程序完成处理。〔习题3.2〕什么是标识符,汇编程序中标识符怎样组成?〔解答〕为了某种需要,每种程序语言都规定了在程序里如何描述名字,程序语言的名字通常被称为标识符;汇编语言中的标识符一般最多由31个字母、数字及规定的特殊符号(如-,$,?,@)组成,不能以数字开头。〔习题3.3〕
什么是保留字,汇编语言的保留字有哪些类型,并举例说明。
〔解答保留字是在每种语言中规定了有特殊意义和功能的不允许再做其它用处的字符串;汇编语言的保留字主要有硬指令助记、伪指令助记符、运算符、寄存器名以及预定义符号等。汇编语言对大小写不敏感。如定义字节数和字符串的DB就是伪指令助记符。〔习题3.4〕汇编语句有哪两种,每个语句由哪4个部分组成?〔解答〕汇编语句有执行性语句和说明性语句;执行性语句由标号、硬指令助记符、操作数和注释四部分组成;说明性语句由名字、伪指令助记符、参数和注释四部分组成- 45 -
〔习题3.5〕汇编语言程序的开发有哪4个步骤,分别利用什么程序完成、产生什么输出文件。〔解答〕⒈
文本编辑程序
汇编语言源程序.asm⒉
目标模块文件.obj⒊
可执行文件.exe或.com⒋
应用程序〔习题3.6〕区分下列概念:(1)变量和标号(2)数值表达式和地址表达式(3)符号常量和字符串常量〔解答〕(1)变量是在程序运行过程中,其值可以被改变的量;标号是由用户自定义的标识符,指向存储单元,表示其存储内容的逻辑地址。(2)数值表达式一般是由运算符连接的各种常数所构成的表达式,地址表达式是由名字、标号以及利用各种的操作符形成的表达式。(3)在程序中,为了使常量更便于使用和阅读,经常将一些常量用常量定义语句定义为符号常量,被一对双引号括起来的若干个字符组成的字符序列被称为字符串常量。- 46 -
〔习题3.7〕假设myword是一个字变量,mybyte1和mybyte2是两个字节变量,指出下列语句中的错误原因。(1) mov byte ptr [bx],1000(2) mov bx,offset myword[si](3) cmp mybyte1,mybyte2(4) mov al,mybyte1+mybyte2(5) sub al,myword(6) jnz myword〔解答〕(1)1000超出了一个字节范围(2)寄存器的值只有程序执行时才能确定,而offset是汇编过程计算的偏移地址,故无法确定,改为lea bx,myword[si](3)两个都是存储单元,指令不允许(4)变量值只有执行时才确定,汇编过程不能计算(5)字节量AL与字量myword,类型不匹配(6)Jcc指令只有相对寻址方式,不支持间接寻址方式〔习题3.8〕OPR1是一个常量,问下列语句中两个AND操作有什么区别?
AND AL,OPR1 AND 0feh〔解答〕- 47 -
前者为“与”操作硬指令助记符,可汇编成机器代码。后者为逻辑运算符,在汇编时进行“与”运算,产生具体数值。 〔习题3.9〕给出下列语句中,指令立即数(数值表达式)的值:(1) mov al,23h AND 45h OR 67h(2) mov ax,h(3) mov ax,NOT(65535 XOR 1234h)(4) mov al,LOW 1234h OR HIGH 5678h(5) mov ax,23h SHL 4(6) mov ax,1234h SHR 6(7) mov al,’a’ AND (NOT(’a’-’A’))(8) mov al,’H’ OR b(9) mov ax,(76543 LT 32768) XOR 7654h〔解答〕注:对于逻辑运算,有关操作数可化为二进制数。(1)67h(2)133h(3)1234h(4)76h- 48 -
(5)0234h(6)0048h(7)41h(8)68h(9)7654h〔习题3.10〕画图说明下列语句分配的存储空间及初始化的数据值:(1) byte_var DB ’ABC’,10,10h,’EF’,3 DUP(-1,?,3 DUP(4))(2) word_var DW 10h,-5,’EF’,3 DUP(?)〔解答〕(1)从低地址开始,依次是(十六进制表达):41
04(2)从低地址开始,依次是(十六进制表达):10
-〔习题3.11〕请设置一个数据段mydataseg,按照如下要求定义变量:(1) my1b为字符串变量:Personal Computer(2) my2b为用十进制数表示的字节变量:20(3) my3b为用十六进制数表示的字节变量:20- 49 -
(4) my4b为用二进制数表示的字节变量:20(5) my5w为20个未赋值的字变量(6) my6c为100的常量(7) my7c表示字符串:Personal Computer〔解答〕mydataseg segmentmy1b
db ‘Personal Computer’my2b
db 1420hmy4b
dw 20 dup(?)my6c
equ 100my6c = 100my7c
equ &Personal Computer&mydataseg ends〔习题3.12〕分析例题3.2的数据段,并上机观察数据的存储形式。
〔解答〕以字节为单位从低地址向高地址依次是:16- 50 -
‘c’‘H’
‘$’12个字符串’month’,每个字符串从低地址到高地址依次是:’m’
‘h’25×4个字节未定义初值的存储单元,操作系统设置为0〔习题3.13〕修改例题3.3,现在用字定义伪指令dw、字串传送指令movsw和字符串显示9号功能调用实现。〔解答〕.model small.stack.datasource
dw htarget
dw 40 dup(?),'$'- 51 -
.code.startupmov ax,dsmov es,axcldmov si,offset sourcemov di,offset targetmov cx,40rep movswmov si,0mov dx,offset targetmov ah,9int 21h.exit 0end〔习题3.14〕变量和标号有什么属性?
〔解答〕段地址:表示变量和标号所在代码段的段地址;
偏移地址:表示变量和标号所在代码段的段内偏移地址;类型:引用变量时,表示是字节、字、双字等数据量。引用该标号时,表示它所在同一个段DDnear类型,还是另外一个段DDfar类型。〔习题3.15〕设在某个程序中有如下片段,请写出每条传送指令执行后寄存器AX的内容:mydata
segmentORG 100HVARW
DB 3,4ALIGN 4VARD
DD HEVENBUFF
DB 10 DUP(?)MESS
DB ’HELLO’BEGIN:
MOV AX,OFFSET MESSMOV AX,TYPE BUFF+TYPE MESS+TYPE VARDMOV AX,SIZEOF VARW+SIZEOF BUFF+SIZEOF MESS
MOV AX,LENGTHOF VARW+LENGTHOF VARD- 53 -
MOV AX,LENGTHOF BUFF+SIZEOF VARWMOV AX,TYPE BEGINMOV AX, OFFSET BEGIN〔解答〕MOV AX, OFFSET MESS
;AX=116HMOV AX, TYPE BUFF+TYPE MESS+TYPE VARD
;AX = 1+1+4 = 06HMOV AX,SIZEOF VARW+SIZEOF BUFF+SIZEOF MESS
;AX = 4+10+5 = 19 = 13HMOV AX,LENGTHOF VARW + LENGTHOF VARD
;AX = 2+1 = 03HMOV AX,LENGTHOF BUFF + SIZEOF VARW
;AX = 10+4 =14 = 0EHMOV AX,TYPE BIGIN
;AX = FF02H (近)
MOV AX,OFFSET BEGIN
;AX = 1BH〔习题3.16〕利用简化段定义格式,必须具有.MODEL语句。MASM定义了哪7种存储模式,TINY和SMALL模式创建什么类型(EXE或COM)程序?设计32位程序应该采用什么模式?- 54 -
〔解答〕MASM定义的7种存储模式是TINY(微型模式、SMALL(小型模式)、COMPACT(紧凑模式)、MEDIUM(中型模式)、LARGE(大型模式)、HUGE(巨大模式)、FLAT(平展模式);TINY用于创建COM类型程序、一般程序都可以选用SMALL模式;设计32位的程序应该采用FLAT模式。〔习题3.17〕源程序中如何指明执行的起始点?源程序应该采用哪个DOS功能调用,实现程序返回DOS?〔解答〕源程序中运用STARTUP伪指令指明执行的起始点;源程序应该采用DOS功能调用的4CH子功能实现程序返回DOS的。〔习题3.18〕在SMALL存储模式下,简化段定义格式的代码段、数据段和堆栈段的缺省段名、定位、组合以及类别属性分别是什么?〔解答〕段定义伪指令
'CODE'.DATA
DGROUP.DATA?
DGROUP.STACK
DGROUP〔习题3.19〕如何用指令代码代替.startup和.exit指令,使得例题3.1a能够在MASM 5.x下汇编通过?- 55 -
〔解答〕;lt301a.asm(文件名).model small.stack.datastring
db ‘Hello,Everybody !’,0dh,0ah.’$’
.codestart:
mov ax ,@datamov ds,axmov dx,offset stringmov ah,9int 21hmov ax ,4c00hint 21hend start〔习题3.20〕创建一个COM程序完成例题3.1的功能。
〔解答〕;lt301a,asm- 56 -
.model tiny.code.startupmov dx,offset stringmov ah,9int 21h.exit 0string
db 'Hello,Everybody!'0dh,0ah,'$'
;end〔习题3.21〕按下面要求写一个简化段定义格式的源程序(1) 定义常量num,其值为5;数据段中定义字数组变量datalist,它的头5个字单元中依次存放-1、0、2、5和4,最后1个单元初值不定;(2) 代码段中的程序将datalist中头num个数的累加和存入datalist的最后1个字单元中。〔解答〕.model small.stack.data- 57 -
equ 5datalist
dw -1,0,2,5,4,?.code.startupmov bx,offset datalistmov cx,numxor ax,ax
add ax,[bx]inc bxinc bxloop againmov [bx],ax.exit 0end〔习题3.22〕按下面要求写一个完整段定义格式的源程序(1)数据段从双字边界开始,其中定义一个100字节的数组,同时该段还作为附加段;- 58 -
(2)堆栈段从节边界开始,组合类型为stack;(3)代码段的类别是’code’,指定段寄存器对应的逻辑段;主程序指定从100h开始,给有关段寄存器赋初值;将数组元素全部设置为64h。〔解答〕stack
segment para ‘stack’dw
512 dup(?)stack
segmentarray
db 100 dup(?)data
segment ‘code’assume cs:code,ds:data,es:data,ss:stackorg 100hstart:
mov ax,datamov ds,axmov es,axmov di,offset arraymov al,64h- 59 -
mov cx,100cldrep stosbmov ax,4c00hint 21hcode
endsend start〔习题3.23〕编制程序完成两个已知双精度数(4字节)A和B相加并将结果存入双精度变量单元SUM中(不考虑溢出)。〔解答〕;xt327.asm.model
small.stack
;定义堆栈段大小为256个字节.dataA
;定义两个双字的数(随意)B
;定义结果,执行后为:h
.code- 60 -
.startupxor
;相对于变量的位移量清零mov
;分高低字分别相加,共两次clc
;清零cfagain:
mov ax, word ptr A[si]
;取第一个数的一个字(先低字后高字)adc ax, word ptr B[si]
;取第二个数的一个字(先低字后高字)
mov word ptr sum[si], ax
;存和的一个字(先低字后高字)
;修改位移量指向下一个字(加2)inc siloop
;cx=cx-1 ,if cx&&0 ,jump again.exit 0end〔习题3.24〕编制程序完成12H、45H、0F3H、6AH、20H、0FEH、90H、0C8H、57H和34H等10个字节数据之和,并将结果存入字节变量SUM中(不考虑溢出)。〔解答〕.startupxor
;位移量清零- 61 -
mov al, bdata[si]
;取第一个数mov cx, num-1
;累加次数again:
;指向下一个数adc al,
;累加loop
;如未完,继续累加mov
;完了,存结果.exit 0end〔习题3.25〕结构数据类型如何说明、结构变量如何定义、结构字段如何引用?〔解答〕结构类型的说明使用一对伪指令STRUCT(MASM5.x是STRUC,功能相同)和ENDS。它们的格式为:结构名 STRUCT…数据定义语句结构名 ENDS结构变量定义的格式为:变量名,结构名
〈字段初值表〉- 62 -
引用结构字段,采用圆点“.”操作符,其格式是:结构变量名.结构字段名。〔习题3.26〕记录数据类型如何说明,记录变量如何定义,width和mask操作符是什么作用?〔解答〕记录类型的说明采用伪指令RECORD,它的格式为:记录名 RECORD 位段[,位段…]定义记录变量的格式:记录变量名 记录名 〈段初值表〉Width记录名/记录位段名操作符返回记录或记录位段所占用的位数。mask记录位段名操作符返回一个8位或16位数值,其中对应该位段的个位为1,其余位为0。第4章 基本汇编语言程序设计
〔习题4.1〕例题4.2如果要求算术右移8位,如何修改程序。〔解答〕思路: 首先由最高位字节向次低位字节传送……次低位字节向最低位字节传送(共7次);再判最高位字节符号位,如为0,送00h到最高位字节;如为1,送ffh到最高位字节。传送可参考例题4.2,不过应从第一号字节送第零号字节,……最高位字节向次低位字节传送;也可以用循环来完成:- 63 -
.model small.stack 256.dataqvar
4321h.code.startupmov cx,7mov si,1again:
mov al, byte ptr qvar[si]mov byte ptr qvar[si-1],alinc siloop againtest al,80hjz ezzmov bl,0ffhjmp
mov bl,0done:
mov byte ptr qvar[7],bl.exit 0end〔习题4.2〕例题4.2如果要求算术左移7位,如何用移位指令实现。
〔解答〕- 64 -
思路:可设计外循环体为8个字节左移一次,方法是:最低位字节算术左移一次,
次低位字节至最高位字节依次带 CF 位循环左移一次(内循环共8次),外循环体控制执行7次即可。.model small.stack 256.dataqvar
4321h.code.startupmov dx, 7
;外循环次数mov ax, byte ptr qvar[0]
;最低位字节送axlpp:
;最低位字节左移一次,其d7移入CF位mov
si, 1mov cx, 7
;内循环次数again:
rcl byte ptr qvar[si], 1
;高位字节依次左移 P50inc
againdec dxjnz
lpp.exit 0.end- 65 -
〔习题4.3〕将AX寄存器中的16位数连续4位分成一组,共4组,然后把这4组数分别放在AL、BL、CL和DL寄存器中。〔解答〕思路:设这四组从低位到高位分别放在AL、BL、CL和DL寄存器中。仅列出代码段:mov bl, al
;将al中的两组分开and al, 0fh
;屏蔽高四位后送almov cl, 4
;原al中的数据逻辑右移4次送blshr bl, clmov dl, ah
;将ah中的两组分开and dl, 0f0h
;屏蔽低高四位后送dlmov cl, 4
;原ah中的数据逻辑右移4次送dlshr dl, clmov cl, ah
;屏蔽高四位后送cland cl, 0fh〔习题4.4〕编写一个程序,把从键盘输入的一个小写字母用大写字母显示出来。〔解答〕getkey:
;从键盘输入,出口:al存键值int 21hcmp
;判键值是小写字母?jb
getkay- 66 -
getkaysub al,20h
;是小写字母转换为大写字母mov dl,almov ah, 02h
;显示int 21h〔习题4.5〕已知用于LED数码管显示的代码表为:LEDtable
DB 0c0h,0f9h,0a4h,0b0h,99h,92h,82h,0f8hDB 80h,90h,88h,83h,0c6h,0c1h,86h,8eh它依次表示0 ~ 9、A ~ F这16个数码的显示代码。现编写一个程序实现将lednum中的一个数字(0 ~ 9、A ~ F)转换成对应的LED显示代码。〔解答〕.model small.stack 256.dataLEDtable
DB 0c0h,0f9h,0a4h,0b0h,99h,92h,82h,0f8hDB 80h,90h,88h,83h,0c6h,0clh、86h,8ehlednum
DB ?.code.startupmov bx, offset LEDtablemov al, lednum- 67 -
;al中存有对应的LED显示代码.exit 0end〔习题4.6〕编制一个程序,把变量bufX和bufY中较大者存入bufZ;若两者相等,则把其中之一存入bufZ中。假设变量存放的是8位无符号数。〔解答〕.model small.stack 256.databufx
db ?.code.startupmov al, bufXmov bl, bufYcmp al,blja nextmov bufZ, bljmp donenext: mov bufZ, aldone:
.exit 0- 68 -
end〔习题4.7〕设变量bufX为有符号16位数,请将它的符号状态保存在signX,即:如果X大于等于0,保存0;如果X小于0,保存-1(ffh)。编写该程序。〔解答〕.model small.stack.databufX
dw -7signX
db ?.code.startupcmp bufX,0test bufX,80hjljnz nextmov signX,0jmp donenext:
mov signX,-1done:
.exit 0end〔习题4.8〕bufX、bufY和bufZ是3个有符号16进制数,编写一个比较相等关系的程序:(1)如果这3个数都不相等,则显示0;- 69 -
(2)如果这3个数中有两个数相等,则显示1;(3)如果这3个数都相等,则显示2。〔解答〕.model small.stack 256.databufx
dw ?.code.startupmov ax,
bufXmov bx,
bufYmov cx,
bufZmov dl, '0'cmp ax,bxjnz next1inc dlnext1:
cmp ax,cxjnz next2inc dlnext2:
cmp bx,cx- 70 -
jnz next3inc dlnext3:
cmp dl,’3’jb next4mov dl,’2’next4:
mov ah,02h
;显示int 21h.exit 0end
〔习题4.9〕例题4.8内外循环次数共是多少?如果要求按从大到小排序,程序如何修改?〔解答〕外循环次数是: count-1次 (19次)内循环次数是: (count-1)!次
( 19! 次)内外循环次数共是 count-1 + (count-1)!次 ,即 19+19!次〔习题4.10〕串操作指令常要利用循环结构,现在不用串操作指令实现字符串string1内容传送到字符串string2,字符长度为count。〔解答〕.model
small.stack 256.data- 71 -
'good morning!'len
$-string1string2
len dup(?).code.startupmov cx, len
;字符数mov si, offset string1
;源指针mov di, offset string2
;目标指针again:
mov al, [si]
;送一个字符mov [di], alinc si
;修改指针inc di
;修改指针loop again
;cx=cx-1,cx=0时退出循环.exit 0end〔习题4.11〕不用串操作指令求主存0040h : 0开始的一个64KB物理段中共有多少个空格?〔解答〕这里仅列出主程序段:mov ax,0040h
;送段地址mov ds, axxor si, si
;偏移量地址- 72 -
xor cx, cx
;计数(循环次数)xor dx, dx
;空格计数器清零again:
cmp [si], 20h
;与空格的ASCII码比较jne
;不是空格,转inc dx
;是空格,空格数加1next:
;修改地址指针loop again
;cx=cx-1,如cx=0 退出循环.exit 0end〔习题4.12〕编程实现把键入的一个字符,用二进制形式(0 / 1)显示出它的ASCII代码值。〔解答〕.model small.stack 256.datastri1
db 'please input',0dh,0ah,'$'.code.startupmov
dx,offset stri1mov ah,09hint 21hmov ah, 01h- 73 -
int 21hmov cx, 8again:
xor dl,dlshl al, 1adc dl, '0'mov ah,02hint 21hloop again.exit 0end〔习题4.13〕编写程序,要求从键盘接收一个数bellN(0 ~ 9),然后响铃bellN次。〔解答〕.model small.stack.datastri1
db 'please input number:1--9',0dh,0ah,'$'.code.startupagain:
dx,offset stri1
;显示stri1,提示输入mov ah,09hint 21h- 74 -
mov ah,01h
;调用输入一个字符int
;输入一个字符存在al中cmp al, '1'
;判该字符,如不在‘1’--‘9’jb
;重新输入cmp al, '9'ja
againand al,0fh
;在‘1’--‘9’,屏蔽高4位mov cl, al
;振铃次数送cxxor ch,chabc:
mov dl, 07h
;调用一次振铃mov ah, 02hint 21hloop abc.exit 0end〔习题4.14〕编写程序,将一个包含有20个有符号数据的数组arrayM分成两个数组:正数数组arrayP和负数数组arrayN,并分别把这两个数组中的数据个数显示出来。〔解答〕.model smallinclude io.inc.stack- 75 -
.dataarrayM
1,2,3,4,5,6,0,-3,-5,-6,0,7,6,90,-18,-23,34,7,9,8
;正数数组arrayN
;负数数组dispP
db 'Plus Number: ','$'dispN
db 0dh,0ah,'Negs Number: ','$'.code.startupmov cx, 20
;源数组元素数xor bx, bx
;设bh为正数个数,bl为负数个数,均清零
xor si, si
;源数组地址位移量again:
;循环20次mov ax, arrayM[si]
;取一个元素cmp ax,0
;判正数jl Neginc bh
;是,正数个数加1jmp nextNeg:
;否,负数个数加1next:
;修改位移量loop again
;循环次数减1mov ah,09h
;调用显示字符串功能mov dx, offset dispP
;显示个数- 76 -
21hmov al,bhca 调用I/O子程序库中的子程序mov ah,09h
;调用显示字符串功能mov dx, offset dispN
;显示个数int
21hmov al,blca 调用I/O子程序库中的子程序.exit 0end〔习题4.15〕编写计算100个正整数之和的程序。如果和不超过16位字的范围(65535),则保存其和到wordsum,如超过则显示‘overflow’。〔解答〕.model small.stack.datanum
equ 100wlist
dw num dup(?)wordsum
db 'overflow. $'.code.startup- 77 -
mov bx,offset wlistmov cx,numxor ax,axagain:
add ax,[bx]jc nextinc bxinc bxloop againmov [bx],axjmp donenext:
mov dx,offset errormov ah,9int 21hdone:
.exit 0end〔习题4.16〕编程判断主存0070h:0开始的1KB中有无字符串‘DEBUG’。这是一个字符串包含的问题,可以采用逐个向后比较的简单算法。〔解答〕.model small.stack.datadisp1
db 'There is
DEBUG in the aera!' ,0dh,0ah,‘$'- 78 -
db 'There is no
DEBUG in the aera!' ,0dh,0ah,‘$'
.code.startupmov ax, 0070h
;送段地址mov ds, axxor si, simov cx,1024cmp [si], 'D'jne nextinc sicmp [si], 'E'jne nextinc sicmp [si], 'B'jne nextinc sicmp [si], 'U'jne nextinc sicmp [si], 'G'je yesnext:
;与‘D'比较
;不是,转
;是‘DEBUG',转
;不是,地址增1- 79 - ;地址指针清零;是,地址增
loop again
mov dx, offset disp2
;没找到,显示disp2jmp
mov dx, offset disp1
;找到,显示disp1dsp:
mov ah, 09hint 21h.exit 0end〔习题4.17〕编程把一个16位无符号二进制数转换成为用8421BCD码表示的5位十进制数。转换算法可以是:用二进制数除以10000,商为“万位”,再用余数除以1000,得到“千位”;依次用余数除以100、10和1,得到“百位”、“十位”和“个位”。〔解答〕.model small.stack 256.datavar
5 dup(?).code.startupmov ax, varmov bx, 10000- 80 -
mov cl, 10xor si, sixor dx, dxagain:
bxmov dbcd[si], alinc
sixchg ax, bxdiv
clxchg ax, bxcmp si,5jnz again.exit 0end〔习题4.18〕没有。。。〔习题4.19〕--〔习题4.20〕--〔习题4.21〕--〔习题4.22〕过程定义的一般格式是怎样的?子程序入口为什么常有PUSH指令、出口为什么有POP指令?下面的程序段有什么不妥吗?若有,请改正:crazy
PROCpush axxor ax,ax- 81 -xor dx,dx again:
add ax,[bx]
adc dx,0inc bxinc bxloop again
retENDP crazy 〔解答〕crazy
add ax,[bx]
loop again
retENDP crazy;crazy PROC ;
xor ax,ax ;
xor dx,dx ;again:
add ax,[bx] ;
adc dx,0 ;
loop again
ret ; crazy
ENDP- 82 -
〔习题4.23〕子程序的参数传递有哪些方法,请简单比较。〔解答〕寄存器、共享变量(公共存储单元)、堆栈用寄存器传递参数是把参数存于约定的寄存器中,这种方法简单易行,经常采用;用变量传递参数是主程序与被调用过程直接用同一个变量名访问传递的参数,就是利用变量传递参数。如果调用程序与被调用程序在同一个源程序文件中,只要设置好数据段寄存器DS,则子程序与主程序访问变量的形式相同,也就是它们共享数据段的变量,调用程序与被调用程序不在同一个源文件中,必须利用public/extern进行声明,才能用变量传递参数,利用变量传递参数,过程的通用性比较差,然而,在多个程序段间,尤其在不同程序的模块间,利用全局变量共享数据也是一种常见的参数传递方法;用堆栈传递参数是主程序将子程序的入口参数压入堆栈,子程序从堆栈中取出参数;子程序将出口压入堆栈,主程序弹出堆栈取得它们。〔习题4.24〕采用堆栈传递参数的一般方法是什么,为什么应该特别注意堆栈平衡问题。〔解答〕采用堆栈传递参数的一般方法是主程序将子程序的入口参数压入堆栈,子程序从堆栈中取出参数子程序将出口参数压入堆栈,主程序弹出堆栈取得它们。因为堆栈采用“先进后出”原则存取,而且返回地址和保护的寄存器等也要存于堆栈,所以要特别注意堆栈平衡问题。〔习题4.25〕什么是子程序的嵌套、递归和重入?- 83 -
〔解答〕子程序中又调用子程序就形成子程序嵌套。子程序中直接或间接调用该子程序本身就形成子程序递归。子程序的重入是指子程序被中断后又被中断服务程序所调用,能够重入的子程序称为可重入子程序。〔习题4.26〕将例题4.7的大写转换为小写字母写成过程,利用AL作为入口、出口参数完成。〔解答〕.model small.stack 256.datastdng
db 'HeLLO eveRyboDy ! ' , 0.code.startupmov bx, offset atringagain: mov al, [bx]call chan
;调用过程mov [bx] , alnext: inc bxjmp againdone: .exit 0chan
;大写转换为小写字母的过程- 84 -
or al, aljz donecmp al,'A'jb nextcmp al, 'Z'ja nextor al, 20hretchan
endpend〔习题4.27〕请按如下子程序说明编写过程:;子程序功能:把用ASCII码表示的两位十进制数转换为对应二进制数;入口参数:DH=十位数的ASCII码,DL=个位数的ASCII码出口参数:AL=对应的二进制数〔解答〕astob
procand dh, 0fh
;十位数的ASCII码转为二进制数mov al, dhmul 10
;al= 10*dhand dl, 0fh
;个位数的ASCII码转为二进制数add al, dl
;al= 10*dh + dl- 85 -
endp〔习题4.28〕写一个子程序,根据入口参数AL=0/1/2,分别实现对大写字母转换成小写、小写转换成大写或大小写字母互换。欲转换的字符串在string中,用0表示结束。〔解答〕Change
;保护bxxor
;位移量清零cmp al,0
;根据入口参数AL=0/1/2,分别处理
chan_0dec aljz
chan_1dec aljz
chan_2jmp donechan_0:
mov al,string[bx]
;实现对大写字母转换成小写
cmp al,0jz donecmp al,’A’
;是大写字母jb next0cmp al,’Z’
;是大写字母- 86 -
ja next0add
string[bx], alnext0:
;位移量加1,指向下一字母jmp
chan_0chan_1:
mov al,string[bx]
;实现对小写字母转换成大写
cmp al,0jz donecmp al,’a’
;是大写字母jb next1cmp al,’z’
;是大写字母ja next1sub
string[bx], alnext0:
;位移量加1,指向下一字母jmp
chan_1chan_2:
mov al,string[bx]
;实现对大写字母转换成小写
cmp al,0jz donecmp al,’A’
;是大写字母jb next2cmp al,’Z’
;是大写字母- 87 -
ja next20add
;转换jmp next2next20:
cmp al,’a’
;是大写字母jb next2cmp al,’z’
;是大写字母ja next2sub
string[bx], alnext2:
;位移量加1,指向下一字母jmp
chan_2done:
;恢复bxretchange
endp〔习题4.29〕编制一个子程序把一个16位二进制数用十六进制形式在屏幕上显示出来,分别运用如下3种参数传递方法,并用一个主程序验证它。(1)采用AX寄存器传递这个16位二进制数(2)采用wordTEMP变量传递这个16位二进制数(3)采用堆栈方法传递这个16位二进制数〔解答〕(1)采用AX寄存器传递这个16位二进制数.model small- 88 -.stack
.datawdata
.startupmov ax,wdata
call dispa
.exit 0dispa
call dldisp
and dl,0fh
call dldisp
call dldisp- 89 -
mov dl,aland dl,0fhcall dldisppop dxpop cxretdispa
endp;dldisp
procpush axor dl,30hcmp dl,39hjbe dldisp1add dl,7dldisp1:
mov ah,2int 21hpop axretdldisp
endpend(2)采用wordTEMP变量传递这个16位二进制数
.model small- 90 -
.stack.datawdata
dw 34abhwordtemp
dw ?.code.startupmov ax,wdatamov wordtemp,axcall dispa.exit 0;dispa
procpush cxpush dxmov cl,4mov dl,byte ptr wordtemp+1
shr dl,clcall dldispmov dl,byte ptr wordtemp+1
and dl,0fhcall dldispmov dl,byte ptr wordtemp
shr dl,clcall dldispmov dl,byte ptr wordtemp
and dl,0fhcall dldisppop dxpop cxretdispa
endp;dldisp
procpush axor dl,30hcmp dl,39hjbe dldisp1add dl,7dldisp1:
mov ah,2int 21hpop axretdldisp
endpend- 92 -
(3)采用堆栈方法传递这个16位二进制数
.model small.stack.datawdata
dw 34abh.code.startuppush wdatacall dispapop ax.exit 0;dispa
procpush bpmov bp,sppush axpush cxpush dxmov ax,[bp+4]mov cl,4mov dl,ahshr dl,add sp,2- 93 -call dldisp
and dl,0fh
call dldisp
call dldisp
and dl,0fh
call dldisp
cmp dl,39h
jbe dldisp1- 94 -
add dl,7dldisp1:
mov ah,2int 21hpop axretdldisp
endpend〔习题4.30〕设有一个数组存放学生的成绩(0 ~ 100),编制一个子程序统计0 ~ 59分、60 ~ 69分、70 ~ 79分、80 ~ 89分、90 ~ 100分的人数,并分别存放到scoreE、scoreD、score C、score B及score A单元中。编写一个主程序与之配合使用。〔解答〕.model small.stack.datascore
db 70,86,90,45,60,96,100,0,...
;全班成绩数组count
;总人数scoreE
;0--59分人数scoreD
;60--69分人数scoreC
;70--79分人数scoreB
;80--89分人数scoreA
;90--99分人数- 95 -
.code.startuplea bx, scoremov cx, countagain:mov al,[bx]
;取一个成绩call tjrs
;调用统计分段人数inc bx
;调整指针loog again
;cx-cx-1,cx=0退出循环
.exit 0tjrs
proc ;统计分段人数cmp al, 60jae
;al&= 60转inc
;al&60,0--59分的人数加1
jmp next4next0:
cmp al, 70jae
scoreDjmp next4next1:
cmp al, 80jae
scoreC- 96 -
jmp next4next2:
cmp al, 90jae
next4next3:
scoreAnext4:
endpend〔习题4.31〕编写一递归子程序,计算指数函数X n 的值。
〔解答〕model small.stack.datax
dw ?.code.startupmov bx,xpush bxmov bx,n- 97 -push bx
call zshhsu
.exit 0 zshhsu
mov ax,[bp+8]
jne zshhsu1
inc axjmp zshhsu2 zshhsu1:
pop bx- 98 -mul bxzshhsu2:
mov [bp+8],ax
pop bppop axpop bxretzshhsu
endpend- 99 -
上一篇: 下一篇:
All rights reserved Powered by
copyright &copyright 。文档资料库内容来自网络,如有侵犯请联系客服。

我要回帖

更多关于 条件运算符判断0 的文章

 

随机推荐