汇编语言程序设计第四版第4章课后答案.docx
- 文档编号:26046856
- 上传时间:2023-06-17
- 格式:DOCX
- 页数:26
- 大小:22.17KB
汇编语言程序设计第四版第4章课后答案.docx
《汇编语言程序设计第四版第4章课后答案.docx》由会员分享,可在线阅读,更多相关《汇编语言程序设计第四版第4章课后答案.docx(26页珍藏版)》请在冰豆网上搜索。
汇编语言程序设计第四版第4章课后答案
汇编语言程序设计第四版
【课后习题答案】--囮裑為檤第4章基本汇编语言程序设计
〔习题4.1〕例题4.2如果要求算术右移8位,如何修改程序。
〔解答〕
思路:
首先由最高位字节向次低位字节传送……次低位字节向最低位字节传送(共7次;再判最高位字节符号位,如为0,送00h到最高位字节;如为1,送ffh到最高位字节。
传送可参考例题4.2,不过应从第一号字节送第零号字节,……最高位字节向次低位字节传送;也可以用循环来完成:
.modelsmall
.stack256
.data
qvardq1234567887654321h
.code
.startup
movcx,7
movsi,1
again:
moval,byteptrqvar[si]
movbyteptrqvar[si-1],al
incsi
loopagain
testal,80h
jzezz
movbl,0ffh
jmpdone
ezz:
movbl,0
done:
movbyteptrqvar[7],bl
.exit0
end
〔习题4.2〕例题4.2如果要求算术左移7位,如何用移位指令实现。
〔解答〕
思路:
可设计外循环体为8个字节左移一次,方法是:
最低位字节算术左移一次,次低位字节至最高位字节依次带CF位循环左移一次(内循环共8次,外循环体控制执行7次即可。
.modelsmall
.stack256
.data
qvardq1234567887654321h
.code
.startup
movdx,7;外循环次数
movax,byteptrqvar[0];最低位字节送ax
lpp:
shlax,1;最低位字节左移一次,其d7移入CF位
movsi,1
movcx,7;内循环次数
again:
rclbyteptrqvar[si],1;高位字节依次左移P50
incsi
loopagain
decdx
jnzlpp
.exit0
.end
〔习题4.3〕将AX寄存器中的16位数连续4位分成一组,共4组,然后把这4组数分别放在AL、BL、CL和DL寄存器中。
〔解答〕
思路:
设这四组从低位到高位分别放在AL、BL、CL和DL寄存器中。
仅列出代码段:
movbl,al;将al中的两组分开
andal,0fh;屏蔽高四位后送al
movcl,4;原al中的数据逻辑右移4次送bl
shrbl,cl
movdl,ah;将ah中的两组分开
anddl,0f0h;屏蔽低高四位后送dl
movcl,4;原ah中的数据逻辑右移4次送dl
shrdl,cl
movcl,ah;屏蔽高四位后送cl
andcl,0fh
〔习题4.4〕编写一个程序,把从键盘输入的一个小写字母用大写字母显示出来。
〔解答〕
getkey:
movah,1;从键盘输入,出口:
al存键值
int21h
cmpal,'a';判键值是小写字母?
jbgetkay
cmpal,'z'
jagetkay
subal,20h;是小写字母转换为大写字母
movdl,al
movah,02h;显示
int21h
〔习题4.5〕已知用于LED数码管显示的代码表为:
LEDtableDB0c0h,0f9h,0a4h,0b0h,99h,92h,82h,0f8h
DB80h,90h,88h,83h,0c6h,0c1h,86h,8eh
它依次表示0~9、A~F这16个数码的显示代码。
现编写一个程序实现将lednum中的一个数字(0~9、A~F转换成对应的LED显示代码。
〔解答〕
.modelsmall
.stack256
.data
LEDtableDB0c0h,0f9h,0a4h,0b0h,99h,92h,82h,0f8h
DB80h,90h,88h,83h,0c6h,0clh、86h,8eh
lednumDB?
.code
.startup
movbx,offsetLEDtable
moval,lednum
xlat;al中存有对应的LED显示代码
.exit0
end
〔习题4.6〕编制一个程序,把变量bufX和bufY中较大者存入bufZ;若两者相等,则把其中之一存入bufZ中。
假设变量存放的是8位无符号数。
〔解答〕
.modelsmall
.stack256
.data
bufxdb?
bufYdb?
bufzdb?
.code
.startup
moval,bufX
movbl,bufY
cmpal,bl
janext
movbufZ,bl
jmpdone
next:
movbufZ,al
done:
.exit0
end
〔习题4.7〕设变量bufX为有符号16位数,请将它的符号状态保存在signX,即:
如果X大于等于0,保存0;如果X小于0,保存-1(ffh。
编写该程序。
〔解答〕
.modelsmall
.data
bufXdw-7
signXdb?
.code
.startup
cmpbufX,0;testbufX,80h
jlnext;jnznext
movsignX,0
jmpdone
next:
movsignX,-1
done:
.exit0
end
〔习题4.8〕bufX、bufY和bufZ是3个有符号16进制数,编写一个比较相等关系的程序:
(1如果这3个数都不相等,则显示0;
(2如果这3个数中有两个数相等,则显示1;
(3如果这3个数都相等,则显示2。
〔解答〕
.modelsmall
.stack256
.data
bufxdw?
bufYdw?
bufzdw?
.code
.startup
movax,bufX
movbx,bufY
movcx,bufZ
movdl,'0'
cmpax,bx
jnznext1
incdl
next1:
cmpax,cx
jnznext2
incdl
next2:
cmpbx,cx
jnznext3
incdl
next3:
cmpdl,‟3‟
jbnext4
movdl,‟2‟
next4:
movah,02h;显示
.exit0
end
〔习题4.9〕例题4.8内外循环次数共是多少?
如果要求按从大到小排序,程序如何修改?
〔解答〕
外循环次数是:
count-1次(19次
内循环次数是:
(count-1!
次(19!
次
内外循环次数共是count-1+(count-1!
次,即19+19!
次
〔习题4.10〕串操作指令常要利用循环结构,现在不用串操作指令实现字符串string1内容传送到字符串string2,字符长度为count。
〔解答〕
.modelsmall
.stack256
.data
string1db'goodmorning!
'
len=$-string1
string2dblendup(?
.code
.startup
movcx,len;字符数
movsi,offsetstring1;源指针
movdi,offsetstring2;目标指针
again:
moval,[si];送一个字符
mov[di],al
incsi;修改指针
incdi;修改指针
loopagain;cx=cx-1,cx=0时退出循环
.exit0
end
〔习题4.11〕不用串操作指令求主存0040h:
0开始的一个64KB物理段中共有多少个空格?
〔解答〕
这里仅列出主程序段:
movax,0040h;送段地址
movds,ax
xorsi,si;偏移量地址
xorcx,cx;计数(循环次数
xordx,dx;空格计数器清零
again:
cmp[si],20h;与空格的ASCII码比较
jnenext;不是空格,转
incdx;是空格,空格数加1
next:
incsi;修改地址指针
loopagain;cx=cx-1,如cx=0退出循环
.exit0
end
〔习题4.12〕编程实现把键入的一个字符,用二进制形式(0/1显示出它的ASCII代码值。
〔解答〕
.modelsmall
.stack256
.data
stri1db'pleaseinput',0dh,0ah,'$'
.code
.startup
movdx,offsetstri1
movah,09h
int21h
movah,01h
int21h
movcx,8
again:
xordl,dl
shlal,1
adcdl,'0'
movah,02h
int21h
loopagain
.exit0
end
〔习题4.13〕编写程序,要求从键盘接收一个数bellN(0~9,然后响铃bellN次。
〔解答〕
.modelsmall
.stack
.data
stri1db'pleaseinputnumber:
1--9',0dh,0ah,'$'
.code
.startup
again:
movdx,offsetstri1;显示stri1,提示输入
movah,09h
int21h
movah,01h;调用输入一个字符
int21h;输入一个字符存在al中
cmpal,'1';判该字符,如不在„1‟--„9‟
jbagain;重新输入
cmpal,'9'
andal,0fh;在„1‟--„9‟,屏蔽高4位
movcl,al;振铃次数送cx
xorch,ch
abc:
movdl,07h;调用一次振铃
movah,02h
int21h
loopabc
.exit0
end
〔习题4.14〕编写程序,将一个包含有20个有符号数据的数组arrayM分成两个数组:
正数数组arrayP和负数数组arrayN,并分别把这两个数组中的数据个数显示出来。
〔解答〕
.modelsmall
includeio.inc
.stack
.data
arrayMdb1,2,3,4,5,6,0,-3,-5,-6,0,7,6,90,-18,-23,34,7,9,8;源数组
arrayPdb20dup(?
;正数数组
arrayNdb20dup(?
;负数数组
dispPdb'PlusNumber:
','$'
dispNdb0dh,0ah,'NegsNumber:
','$'
.code
.startup
movcx,20;源数组元素数
xorbx,bx;设bh为正数个数,bl为负数个数,均清零
xorsi,si;源数组地址位移量
again:
;循环20次
movax,arrayM[si];取一个元素
cmpax,0;判正数
jlNeg
incbh;是,正数个数加1
jmpnext
Neg:
incbl;否,负数个数加1
next:
incsi;修改位移量
loopagain;循环次数减1
movah,09h;调用显示字符串功能
movdx,offsetdispP;显示个数
int21h
moval,bh
calldispuib;调用I/O子程序库中的子程序
movah,09h;调用显示字符串功能
movdx,offsetdispN;显示个数
moval,bl
calldispuib;调用I/O子程序库中的子程序
.exit0
end
〔习题4.15〕编写计算100个正整数之和的程序。
如果和不超过16位字的范围(65535,则保存其和到wordsum,如超过则显示„overflow‟。
〔解答〕
.modelsmall
.stack
.data
numequ100
wlistdwnumdup(?
wordsumdw?
errordb'overflow.$'
.code
.startup
movbx,offsetwlist
movcx,num
xorax,ax
again:
addax,[bx]
jcnext
incbx
incbx
loopagain
mov[bx],ax
jmpdone
next:
movdx,offseterror
movah,9
int21h
done:
.exit0
end
〔习题4.16〕编程判断主存0070h:
0开始的1KB中有无字符串„DEBUG‟。
这是一个字符串包含的问题,可以采用逐个向后比较的简单算法。
〔解答〕
.modelsmall
.stack
.data
disp1db'ThereisDEBUGintheaera!
',0dh,0ah,„$'
disp2db'ThereisnoDEBUGintheaera!
',0dh,0ah,„$'
.code
.startup
movax,0070h;送段地址
movds,ax
xorsi,si;地址指针清零
movcx,1024
cmp[si],'D';与„D'比较
jnenext;不是,转
incsi;是,地址增1
cmp[si],'E';同上
jnenext
incsi
cmp[si],'B'
jnenext
incsi
cmp[si],'U'
jnenext
incsi
cmp[si],'G'
jeyes;是„DEBUG',转
next:
incsi;不是,地址增1
loopagain;循环
no:
movdx,offsetdisp2;没找到,显示disp2
jmpdsp
yes:
movdx,offsetdisp1;找到,显示disp1
dsp:
movah,09h
int21h
.exit0
end
〔习题4.17〕编程把一个16位无符号二进制数转换成为用8421BCD码表示的5位十进制数。
转换算法可以是:
用二进制数除以10000,商为“万位”,再用余数除以1000,得到“千位”;依次用余数除以100、10和1,得到“百位”、“十位”和“个位”。
〔解答〕
.modelsmall
.stack256
.data
vardw3546
dbcddb5dup(?
.code
.startup
movax,var
movbx,10000
movcl,10
xorsi,si
xordx,dx
again:
divbx
movdbcd[si],al
incsi
xchgax,bx
divcl
xchgax,bx
cmpsi,5
jnzagain
.exit0
end
〔习题4.18〕没有。
。
。
〔习题4.19〕--
〔习题4.20〕--
〔习题4.21〕--
〔习题4.22〕过程定义的一般格式是怎样的?
子程序入口为什么常有PUSH指令、出口为什么有POP指令?
下面的程序段有什么不妥吗?
若有,请改正:
crazyPROC
pushax
xorax,ax
xordx,dx
again:
addax,[bx]
adcdx,0
incbx
incbx
loopagain
ret
ENDPcrazy
〔解答〕
crazyPROC;crazyPROC
pushax;
xorax,ax;xorax,ax
xordx,dx;xordx,dx
again:
addax,[bx];again:
addax,[bx]
adcdx,0;adcdx,0
incbx;incbx
incbx;incbx
loopagain;loopagain
ret;ret
ENDPcrazy;crazyENDP
〔习题4.23〕子程序的参数传递有哪些方法,请简单比较。
〔解答〕
寄存器、共享变量(公共存储单元、堆栈
用寄存器传递参数是把参数存于约定的寄存器中,这种方法简单易行,经常采用;
用变量传递参数是主程序与被调用过程直接用同一个变量名访问传递的参数,就是利用变量传递参数。
如果调用程序与被调用程序在同一个源程序文件中,只要设置好数据段寄存器DS,则子程序与主程序访问变量的形式相同,也就是它们共享数据段的变量,调用程序与被调用程序不在同一个源文件中,必须利用public/extern进行声明,才能用变量传递参数,利用变量传递参数,过程的通用性比较差,然而,在多个程序段间,尤其在不同程序的模块间,利用全局变量共享数据也是一种常见的参数传递方法;
用堆栈传递参数是主程序将子程序的入口参数压入堆栈,子程序从堆栈中取出参数;子程序将出口压入堆栈,主程序弹出堆栈取得它们。
〔习题4.24〕采用堆栈传递参数的一般方法是什么,为什么应该特别注意堆栈平衡问题。
〔解答〕
采用堆栈传递参数的一般方法是主程序将子程序的入口参数压入堆栈,子程序从堆栈中取出参数子程序将出口参数压入堆栈,主程序弹出堆栈取得它们。
因为堆栈采用“先进后出”原则存取,而且返回地址和保护的寄存器等也要存于堆栈,所以要特别注意堆栈平衡问题。
〔习题4.25〕什么是子程序的嵌套、递归和重入?
〔解答〕
子程序中又调用子程序就形成子程序嵌套。
子程序中直接或间接调用该子程序本身就形成子程序递归。
子程序的重入是指子程序被中断后又被中断服务程序所调用,能够重入的子程序称为可重入子程序。
〔习题4.26〕将例题4.7的大写转换为小写字母写成过程,利用AL作为入口、出口参数完成。
〔解答〕
.modelsmall
.stack256
.data
stdngdb'HeLLOeveRyboDy!
',0
.code
.startup
movbx,offsetatring
again:
moval,[bx]
callchan;调用过程
mov[bx],al
next:
incbx
jmpagain
done:
.exit0
chanproc;大写转换为小写字母的过程
oral,al
jzdone
cmpal,'A'
jbnext
cmpal,'Z'
janext
oral,20h
ret
chanendp
end
〔习题4.27〕请按如下子程序说明编写过程:
;子程序功能:
把用ASCII码表示的两位十进制数转换为对应二进制数
;入口参数:
DH=十位数的ASCII码,DL=个位数的ASCII码
;出口参数:
AL=对应的二进制数
〔解答〕
astobproc
anddh,0fh;十位数的ASCII码转为二进制数
moval,dh
mul10;al=10*dh
anddl,0fh;个位数的ASCII码转为二进制数
addal,dl;al=10*dh+dl
ret
astobendp
〔习题4.28〕写一个子程序,根据入口参数AL=0/1/2,分别实现对大写字母转换成小写、小写转换成大写或大小写字母互换。
欲转换的字符串在string中,用0表示结束。
〔解答〕
Changeproc
Pushbx;保护bx
xorbx,bx;位移量清零
cmpal,0;根据入口参数AL=0/1/2,分别处理
jzchan_0
decal
jzchan_1
decal
jzchan_2
jmpdone
chan_0:
moval,string[bx];实现对大写字母转换成小写
cmpal,0
jzdone
cmpal,‟A‟;是大写字母
jbnext0
cmpal,‟Z‟;是大写字母
janext0
addal,20h;转换
movstring[bx],al
next0:
incbx;位移量加1,指向下一字母
jmpchan_0
chan_1:
moval,string[bx];实现对小写字母转换成大写
cmpal,0
jzdone
cmpal,‟a‟;是大写字母
jbnext1
cmpal,‟z‟;是大写字母
janext1
subal,20h;转换
movstring[bx],al
next0:
incbx;位移量加1,指向下一字母
jmpchan_1
chan_2:
moval,string[bx];实现对大写字母转换成小写
cmpal,0
jzdone
cmpal,‟A‟;是大写字母
jbnext2
cmpal,‟Z‟;是大写字母
janext20
addal,20h;转换
jmpnext2
next20:
cmpal,‟a‟;是大写字母
jbnext2
cmpal,‟z‟;是大写字母
janext2
subal,20h;转换
movstring[bx],al
next2:
incbx;位移量加1,指向下一字母
jmpchan_2
done:
popbx;恢复bx
ret
changeendp
〔习题4.29〕编制一个子程序把一个16位二进制数用十六进制形式在屏幕上显示出来,分别运用如下3种参数传递方法,并用一个主程序验证它。
(1采用AX寄存器传递这个16位二进制数
(2采用wordTEMP变量传递这个16位二进制数
(3采用堆栈方法传递这个16位二进制数
〔解答〕
(1采用AX寄存器传递这个16位二进制数
.modelsmall
.stack
.data
.code
.st
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 汇编语言 程序设计 第四 课后 答案