第4章 汇编语言程序设计.docx
- 文档编号:30185596
- 上传时间:2023-08-05
- 格式:DOCX
- 页数:34
- 大小:25.20KB
第4章 汇编语言程序设计.docx
《第4章 汇编语言程序设计.docx》由会员分享,可在线阅读,更多相关《第4章 汇编语言程序设计.docx(34页珍藏版)》请在冰豆网上搜索。
第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;相对寻址
nop
moveax,'?
'
calldispc
labl1:
moveax,'1'
calldispc
jmpnearptrlabl2;相对近转移
nop
moveax,'?
'
calldispc
labl2:
moveax,'2'
calldispc
moveax,offsetlabl3
jmpeax;寄存器间接寻址
nop
moveax,'?
'
calldispc
labl3:
moveax,'3'
calldispc
moveax,offsetlabl4
movnvar,eax
jmpnvar;存储器间接寻址
nop
moveax,'?
'
calldispc
labl4:
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,20h
cmpeax,80h
〔解答〕
CF=1ZF=0SF=1OF=0PF=1
可以使得条件成立、发生转移的指令有:
JCJSJPJNZJNO
〔习题4.7〕
将例题4-4程序修改为实现偶校验。
建议进一步增加显示有关提示信息的功能,使得程序具有更加良好的交互性。
〔解答〕
includeio32.inc
.data
msg1byte'Pleaseinputacharacter:
',0
msg2byte'TheASCIIcodeofthecharateryouenteredis:
',0
msg3byte'Thecodewithevenparityis:
',0
.code
start:
moveax,offsetmsg1
calldispmsg
callreadc
calldispcrlf
movebx,eax
moveax,offsetmsg2
calldispmsg
moveax,ebx
calldispbb
calldispcrlf
andal,7fh
jpnext
oral,80h
next:
movebx,eax
moveax,offsetmsg3
calldispmsg
moveax,ebx
calldispbb
exit0
endstart
〔习题4.8〕
在采用奇偶校验传输数据的接收端应该验证数据传输的正确性。
例如,如果采用偶校验,那么在接收到的数据中,其包含“1”的个数应该为0或偶数个,否则说明出现传输错误。
现在,在接收端编写一个这样的程序,如果偶校验不正确显示错误信息,传输正确则继续。
假设传送字节数据、最高位作为校验位,接收到的数据已经保存在Rdata变量中。
〔解答〕
;数据段
Rdatabyte57h;保存接收的数据
errorbyte'Error!
',0
;代码段
moval,Rdata
andal,0ffh;标志PF反映“1”的个数
jpdone;个数为偶数,正确继续
moveax,offseterror;个数为奇数,显示出错
calldispmsg
done:
〔习题4.9〕
指令CDQ将EAX符号扩展到EDX,即:
EAX最高为0,则EDX=0;EAX最高为1,则EDX=FFFFFFFFH。
请编程实现该指令功能。
〔解答1〕
testeax,8000h;测试最高位
jznext1;最高位为0(ZF=1),转移到标号NEXT1
movedx,0ffffffffh;最高位为1,顺序执行:
设置EDX=FFFFFFFFH
jmpdone;无条件转移,跳过另一个分支
next1:
movdx,0;最高位为0转移到此执行:
设置EDX=0
done:
〔解答2〕
使用移位指令更好。
roleax,1
rcredx,1
saredx,31
roreax,1
〔习题4.10〕
编程,首先测试双字变量DVAR的最高位,如果为1,则显示字母“L”;如果最高位不为1,则继续测试最低位,如果最低位为1,则显示字母“R”;如果最低位也不为1,则显示字母“M”。
〔解答〕
;数据段
dvardword57h
;代码段
moveax,dvar
testeax,80000000h
jnznextl
testeax,1
jnznextr
moval,'M'
jmpdone
nextl:
moval,'L'
jmpdone
nextr:
moval,'R'
done:
calldispc
〔习题4.11〕编写一个程序,先提示输入数字“InputNumber:
0~9”,然后在下一行显示输入的数字,结束;如果不是键入了0~9数字,就提示错误“Error!
”,继续等待输入数字。
〔解答〕
;数据段
inmsgbyte'Inputnumber(0~9):
',0
ermsgbyte0dh,0ah,'Error!
Inputagain:
',0
;代码段
moveax,offsetinmsg;提示输入数字
calldispmsg
again:
callreadc;等待按键
cmpal,'0';数字<0?
jberdisp
cmpal,'9';数字>9?
jaerdisp
calldispcrlf
calldispc
jmpdone
erdisp:
moveax,offsetermsg
calldispmsg
jmpagain
done:
〔习题4.12〕
有一个首地址为ARRAY的20个双字的数组,说明下列程序段的功能。
movecx,20
moveax,0
movesi,eax
sumlp:
addeax,array[esi]
addesi,4
loopsumlp
movtotal,eax
〔解答〕
求这20个双字的和,保存在TOTAL变量,不关进心进位和溢出。
〔习题4.13〕
编程中经常要记录某个字符出现的次数。
现编程记录某个字符串中空格出现的次数,结果保存在SPACE单元。
〔解答〕
;数据段
stringbyte'DoyouhavefunwithAssembly?
',0;以0结尾的字符串
spacedword?
;代码段
movesi,offsetstring
xorebx,ebx;EBX用于记录空格数
again:
moval,[esi]
cmpal,0
jzdone
cmpal,20h;空格的ASCII码是20H
jnenext;不相等、不是空格,转移
incbx;相等、是空格,空格个数加1
next:
incesi
jmpagain;继续循环
done:
movspace,ebx;保存结果
〔习题4.14〕
编写计算100个16位正整数之和的程序。
如果和不超过16位字的范围(65535),则保存其和到WORDSUM,如超过则显示‘Overflow!
’。
〔解答〕
;数据段
arrayword2005,2008,98dup(1394);假设100个16位正整数
wordsumword?
errorbyte'Overflow!
',0
;代码段
andebx,0
movecx,100
xorax,ax
again:
addax,array[ebx*2]
jcover
incebx
loopagain
movwordsum,ax
over:
moveax,offseterror
calldispmsg
〔习题4.15〕
在一个已知长度的字符串中查找是否包含“BUG”子字符串。
如果存在,显示“Y”,否则显示“N”。
〔解答〕
;数据段
stringbyte'Ifyoufindanyerrorintheprogram,youcanDEBUGit.'
count=sizeofstring
bugbyte'BUG'
;代码段
movecx,count
movedi,offsetstring
L1:
movesi,offsetbug
pushedi
movedx,sizeofbug
LN:
moval,[esi]
cmp[edi],al
jneL2
incesi
incedi
decedx
jneLN
popedi
moval,'Y'
jmpL3
L2:
popedi
incedi
loopL1
moval,'N'
L3:
calldispc
〔习题4.16〕
主存中有一个8位压缩BCD码数据,保存在一个双字变量中。
现在需要进行显示,但要求不显示前导0。
由于位数较多,需要利用循环实现,但如何处理前导0和数据中间的0呢?
不妨设置一个标记。
编程实现。
〔解答〕
;数据段
bcddword00371002h
;代码段
movesi,bcd
cmpesi,0
jnzgoon
moval,'0'
calldispc
jmpdone
goon:
movecx,8
xorebx,ebx;EBX=0,表示可能是前导0
again:
rolesi,4
moveax,esi
andeax,0fh;EAX低4位保存当前要显示的BCD码
cmpebx,0;EBX≠0,说明不是前导0,要显示
jnzdisp;EBX=0,说明可能是前导0
cmpeax,0
jznext;EAX=0,说明是前导0,不显示
movebx,1;EAX≠0,没有前导0了,令EBX=1≠0
disp:
addal,30h
calldispc
next:
loopagain
done:
〔习题4.17〕
已知一个字符串的长度,剔除其中所有的空格字符。
请从字符串最后一个字符开始逐个向前判断、并进行处理。
〔解答〕
;数据段
stringbyte'Letushaveatry!
',0dh,0ah,0
;代码段
movecx,sizeofstring
cmpecx,2
jbdone
leaeax,string;显示处理前的字符串
calldispmsg
movesi,ecx
decesi
outlp:
cmpstring[esi],'';检测是否是空格
jnznext;不是空格继续循环
movedi,esi;是空格,进入剔除空格分支
dececx
inlp:
incedi
moval,string[edi];前移一个位置
movstring[edi-1],al
cmpedi,ecx
jbinlp
next:
decesi;继续进行
cmpesi,0
jnzoutlp;为0结束
leaeax,string;显示处理后的字符串
calldispmsg
done:
〔习题4.18〕
第3章习题3.14在屏幕上显示ASCII表,现仅在数据段设置表格缓冲区,编程将ASCII代码值填入留出位置的表格,然后调用显示功能实现(需要利用双重循环)。
〔解答〕
includeio32.inc
.data
tablebyte'|0123456789ABCDEF',13,10
byte'---+-------------------------------',13,10
tab1byte6dup(36dup(?
),13,10)
byte0
.code
start:
movebx,offsettab1
movedx,'|02'
movax,2020h
movesi,6
again0:
mov[ebx],edx
addebx,4
movecx,16
again1:
movwordptr[ebx],ax
addebx,2
incal
loopagain1
addebx,2
addedx,1
decesi
jnzagain0
moveax,offsettable
calldispmsg
exit0
endstart
〔习题4.19〕
请按如下说明编写子程序:
子程序功能:
把用ASCII码表示的两位十进制数转换为压缩BCD码
入口参数:
DH=十位数的ASCII码,DL=个位数的ASCII码
出口参数:
AL=对应BCD码
〔解答〕
asctobproc
shldh,4
moval,dh
anddl,0fh
oral,dl
ret
asctobendp
〔习题4.20〕
乘法的非压缩BCD码调整指令AAM执行的操作是:
AH←AL÷10的商,AL←AL÷10的余数。
利用AAM可以实现将AL中的100内数据转换为ASCII码,程序如下:
xorah,ah
aam
addax,3030h
利用这段程序,编写一个显示AL中数值(0~99)的子程序。
〔解答〕
disp99proc
xorah,ah
aam
addax,3030h
pushax
moval,ah
calldispc
popax
calldispc
ret
disp99endp
〔习题4.21〕
编写一个源程序,在键盘上按一个键,将其返回的ASCII码值显示出来,如果按下ESC键(对应ASCII码是1BH)则程序退出。
请调用书中的HTOASC子程序。
〔解答〕
;代码段,主程序
again:
callreadc
cmpal,1bh
jzdone
movbl,al
moval,':
'
calldispc
moval,bl
rolal,4
callhtoasc;调用子程序
calldispc;显示一个字符
moval,bl
callhtoasc;调用子程序
calldispc;显示一个字符
calldispcrlf
jmpagain
done:
〔习题4.22〕
编写一个子程序,它以二进制形式显示EAX中32位数据,并设计一个主程序验证。
〔解答〕
;代码段,主程序
moveax,8F98FF00H
calldispbd;调用子程序
;代码段,子程序
dispbdproc;32位二进制数的输出
pushecx
pushedx
movecx,32;要输出的字符个数
dbd:
roleax,1;AL循环左移一位
pusheax
andal,01h;取AL最低位
addal,30h;转化成相应的ASCLL码值
calldispc;以二进制的形式显示
popeax
loopdbd
popedx
popecx
ret
dispbdendp
〔习题4.23〕
将例题4-16的32位寄存器改用16位寄存器,仅实现输出-215~+215-1之间的数据。
〔解答〕
;数据段
arrayword12345,-1234,32767,-32768,0,667
writebufbyte6dup(0)
;代码段,主程序
movecx,lengthofarray
movebx,0
again:
movax,array[ebx*2]
callwrite
calldispcrlf
incebx;此时ebx代表array中的第几个数
dececx;此时ecx代表循环的次数
jnzagain
;代码段,子程序
writeproc;子程序开始
pushebx
pushecx
pushedx
movebx,offsetwritebuf;ebx指向显示缓冲区
testax,ax
jnzwrite1
movbyteptr[ebx],30h
incebx
jmpwrite5
write1:
;若不为0则首先判断是正是负
jnswrite2;若为正则跳过下面两步到write2
movbyteptr[ebx],'-'
incebx
negax
write2:
movcx,10
pushcx;将cx=10压入栈,作为退出标志
write3:
;write3是让eax循环除以10并把余数的ASCII码压入栈
cmpax,0
jzwrite4
xordx,dx
divcx
adddx,30h
pushdx
jmpwrite3
write4:
;余数的ASCII码出栈,遇到10终止并转到write5显示结果
popdx
cmpdx,cx
jzwrite5
movbyteptr[ebx],dl
incebx
jmpwrite4
write5:
;显示结果
movbyteptr[ebx],0
moveax,offsetwritebuf
calldispmsg
popedx
popecx
popebx
ret
writeendp
〔习题4.24〕
参考例题4-17,编写实现32位无符号整数输入的子程序,并设计一个主程序验证。
〔解答〕
;数据段
count=10
arraydwordcountdup(0)
tempdword?
readbufbyte30dup(0)
errmsgbyte'Inputerror,enteragain!
',13,10,0
msg1byte'Inputtenunsignednumbers,eachnumberendswithenterkey:
',13,10,0
msg2byte'Checkthenumbersyourinputted:
',13,10,0
;代码段,主程序
moveax,offsetmsg1
calldispmsg
movecx,count
movebx,offsetarray
again:
callread
moveax,temp
mov[ebx],eax
addebx,4
dececx
jnzagain
moveax,offsetmsg2
calldispmsg
movedx,offsetarray
movecx,count
next:
moveax,[edx]
calldispuid
calldispcrlf
addedx,4
dececx
jnznext
;代码段,子程序
readproc
pusheax
pushecx
pushebx
pushedx
read0:
moveax,offsetreadbuf
callreadmsg
testeax,eax
jzreaderr
cmpeax,12
jareaderr
movedx,offsetreadbuf
xorebx,ebx
xorecx,ecx
moval,[edx]
cmpal,'+'
jzread1
cmpal,'-'
jnzread2
jmpreaderr
read1:
incedx
moval,[edx]
testal,al
jzread3;如果为0,则说明该字符串已结束
read2:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第4章 汇编语言程序设计 汇编语言 程序设计