《汇编语言与接口技术》习题解答第三章Word文档下载推荐.docx
《《汇编语言与接口技术》习题解答第三章Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《《汇编语言与接口技术》习题解答第三章Word文档下载推荐.docx(17页珍藏版)》请在冰豆网上搜索。
ret
lucaseendp
习题3.1解答:
参考教材(第60页)
习题3.6
问题:
⏹给出你采用一个源程序格式书写的例题3.1源程序
解答:
.modelsmall
.stack
.data
stringdb’Hello,Assembly!
’,0dh,0ah,’$’
.code
start:
movax,@data
movds,ax
movdx,offsetstring
movah,9
int21h
movax,4c00h
endstart
习题3.12解答:
ORG伪指令
习题3.13解答:
段地址和偏移地址属性,类型属性
习题3.26
⏹过程定义的一般格式是怎样的?
子程序开始为什么常有PUSH指令、返回前为什么常有POP指令?
下面完成16位无符号数累加的子程序有什么不妥吗?
若有,请改正:
crazyPROC;
crazyPROC
pushax;
xorax,ax;
xorax,ax
xordx,dx;
xordx,dx
again:
addax,[bx];
addax,[bx]
adcdx,0;
adcdx,0
incbx;
loopagain;
loopagain
ret;
ENDPcrazy;
crazyENDP
字量求和子程序
入口参数:
BX=数据首址
CX=数据个数
出口参数:
AX=和的低字
DX=和的高字
(进位部分)
习题3.28
⏹请按如下说明编写子程序:
;
子程序功能:
把用ASCII码表示的两位十进制数转换为对应二进制数
DH=十位数的ASCII码,DL=个位数的ASCII码
AL=对应的二进制数
asctobproc
pushcx
;
先转换十位数
anddh,0fh
shldh,1;
乘以10
movch,dh
shldh,1
adddh,ch
;
转换个位数
anddl,0fh
十位数加个位数
adddh,dl
设置出口参数
moval,dh
popcx
ret
asctobendp
习题3.34-1
⏹编写一个计算字节校验和的子程序。
所谓“校验和”是指不记进位的累加,常用于检查信息的正确性。
主程序提供入口参数,有数据个数和数据缓冲区的首地址。
子程序回送求和结果这个出口参数。
传递参数方法自定。
数据段
arraydb12h,25h,0f0h,0a3h,3,68h,71h,0cah,0ffh,90h
countequ$-array;
数组元素个数
resultdb?
;
校验和
代码段(主程序)
movbx,offsetarray;
BX←数组的偏移地址
movcx,count;
CX←数组的元素个数
callchecksum;
调用求和过程
movresult,al;
处理出口参数
习题3.34-2
代码段(子程序)
计算字节校验和的通用过程
DS:
BX=数组的段地址:
偏移地址
CX=元素个数
AL=校验和
说明:
除AX/BX/CX外,不影响其他寄存器
checksumproc
xoral,al;
累加器清0
sum:
addal,[bx];
求和
指向下一个字节
loopsum
checksumendp
〔习题3.17〕
已知用于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显示代码。
〔解答〕
;
LEDtabledb0c0h,0f9h,0a4h,0b0h,99h,92h,82h,0f8h
db80h,90h,88h,83h,0c6h,0clh,86h,8eh
lednumdb0ah
代码段
movbx,offsetLEDtable
moval,lednum
xlat;
al中存有对应的LED显示代码
〔习题3.21〕
例题3.7中,如果要实现所有为1的位都顺序执行相应的处理程序段(而不是例题中仅执行最低为1位的处理程序段),请写出修改后的代码段。
代码段
moval,number
movbx,0;
BX←记录为1的位数
restart:
cmpal,0;
AL=0结束
jzdone
shral,1;
最低位右移进入CF
jcnext;
为1,转移
incbx;
不为1,继续
jmpagain
next:
pushax
pushbx
shlbx,1;
位数乘以2(偏移地址要用2个字节单元)
jmpaddrs[bx];
间接转移:
IP←[table+BX]
以下是各个处理程序段
fun0:
movdl,'
0'
jmpdisp
fun1:
1'
fun2:
2'
fun3:
3'
fun4:
4'
fun5:
5'
fun6:
6'
fun7:
7'
disp:
movah,2;
显示一个字符
popbx
popax
jmprestart
…
〔习题3.24〕
编写计算100个正整数之和的程序。
如果和不超过16位字的范围(65535),则保存其和到wordsum,如超过则显示‘Overflow!
’。
countequ100
parraydwcountdup(?
);
假设有100个数据
wordsumdw0
msgdb‘overflow’,’$’
movcx,count
movax,0
movbx,offsetparray
jncnext
movdx,offsetmsg
int21h;
显示溢出信息
jmpdone;
然后,跳出循环体
addbx,2
loopagain
movwordsum,ax
…
〔习题3.25〕
编程把一个16位无符号二进制数转换成为用8421BCD码表示的5位十进制数。
转换算法可以是:
用二进制数除以10000,商为“万位”,再用余数除以1000,得到“千位”;
依次用余数除以100、10和1,得到“百位”、“十位”和“个位”。
wjxt325.asm
.modelsmall
.stack256
.data
arraydw?
源字数据
dbcddb5dup(?
五位bcd结果,高对高低对低
.startup
movdx,array;
取源数据(余数)
movbx,10000;
除数
movcx,10;
除数系数
movsi,4;
目的数据高位位移量
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
end
〔习题3.27〕
编写一个源程序,在键盘上按一个键,将从AL返回的ASCII码值显示出来,如果按下ESC键则程序退出。
请调用书中的HTOASC子程序。
movah,1
cmpal,1bh;
ESC的ASCII码是1bh
jedone
callhtoasc
movah,2
int21h
〔习题3.29〕
调用HTOASC子程序,编写显示一个字节的16进制数、后跟“H”的子程序。
DIPASCproc;
AL=要显示的一个16进制数
pushdx
pushax
movcl,4;
转换高位
shral,cl
callHTOASC
movdl,al;
显示
popax;
转换低位
movdl,’H’;
显示一个字母“H”
DIPASCendp
HTOASCproc;
将AL低4位表达的一位16进制数转换为ASCII码
andal,0fh
cmpal,9
jbehtoasc1
addal,37h;
是0AH~0FH,加37H转换为ASCII码
ret;
子程序返回
htoasc1:
addal,30h;
是0~9,加30H转换为ASCII码
HTOASCendp
〔习题3.35〕
编制3个子程序把一个16位二进制数用4位16进制形式在屏幕上显示出来,分别运用如下3种参数传递方法,并配合3个主程序验证它。
⑴采用AX寄存器传递这个16位二进制数
⑵采用temp变量传递这个16位二进制数
⑶采用堆栈方法传递这个16位二进制数
⑴
wdatadw34abh
.code
.startup
movax,wdata
calldispa
dispaproc
movcl,4
movdl,ah
shrdl,cl
calldldisp
movdl,al
dispaendp
dldispproc
ordl,30h
cmpdl,39h
jbedldisp1
adddl,7
dldisp1:
movah,2
dldispendp
⑵
wordtempdw?
movwordtemp,ax
movdl,byteptrwordtemp+1
movdl,byteptrwordtemp
⑶
pushwdata
popax;
addsp,2
pushbp
movbp,sp
movax,[bp+4]
popbp