常见汇编程序源代码示例.docx
《常见汇编程序源代码示例.docx》由会员分享,可在线阅读,更多相关《常见汇编程序源代码示例.docx(38页珍藏版)》请在冰豆网上搜索。
![常见汇编程序源代码示例.docx](https://file1.bdocx.com/fileroot1/2023-1/21/21fb6d84-964a-4192-9612-5b91f4bac3e1/21fb6d84-964a-4192-9612-5b91f4bac3e11.gif)
常见汇编程序源代码示例
包含14个常见的汇编程序源代码,所有代码在VC6.0中调试通过;
汇编程序采用《微机原理接口与技术》(钱晓婕)一书中所用的框架。
1.
编写程序,计算下面函数的值并输出。
includeio32.inc
.code
start:
callreadsid
cmpeax,0
jlsmall
cmpeax,10
jlemid
jmplarge
small:
imuleax,2
jmpdone
mid:
imuleax,3
jmpdone
large:
imuleax,4
jmpdone
done:
calldispsid
exit0
endstart
2.输入一个年份(调用readuid子程序),判断是否是闰年.
includeio32.inc
.data
yes_msgbyte'isleap',13,10,0
no_msgbyte'noleap',13,10,0
.code
start:
callreaduid
movedx,0
movecx,4
divecx
cmpedx,0
jefirst
jmpsecond
first:
movedx,0
movecx,100
divecx
jneleap
jmpsecond
second:
movedx,0
movecx,400
divecx
jeleap
jmpnoleap
leap:
moveax,offsetyes_msg
calldispmsg
jmpdone
noleap:
moveax,offsetno_msg
calldispmsg
jmpdone
done:
exit0
endstart
3.输入三个无符号整数(调用readuid子程序),判断并输出这三个数是否能构成一个三角形的三条边。
若这三个数能构成一个三角形的三条边,输出三角形的形状:
斜三角形、等腰三角形、等边三角形。
includeio32.inc
.data
msg_dengyaobyte'dengyao',13,10,0;等腰三角形
msg_dengbianbyte'dengbian',13,10,0;等边三角形
msg_zhijiaobyte'zhijiao',13,10,0;直角三角形
msg_xiesanjiaobyte'xiesanjiaoxing',13,10,0;斜三角形
msg_wrongbyte'wrong',13,10,0;无法构成三角形
sqrdword0
.code
;在ebx,ecx,edx分别保存三条边的长度
start:
callreaduid;读取第一个数和第二个数到ebx、ecx
movebx,eax
callreaduid
movecx,eax
cmpebx,ecx;确保ebx<=ecx
jggreat
jmpnext
great:
xchgebx,ecx
next:
;读取第三个数到edx
callreaduid
movedx,eax
cmpebx,edx
jgthirdsmall;如果第三个数最小
cmpecx,edx
jgthirdmid;如果第三个数在最中间
jmporder
;如果第三个数最小
thirdsmall:
moveax,edx
movedx,ecx
movecx,ebx
movebx,eax
jmporder
;如果第三个数在最中间
thirdmid:
xchgecx,edx
jmporder
;执行至此,三个数(ebx,ecx,edx)已经从小到大排序
order:
moveax,ebx
addeax,ecx
cmpeax,edx;最小的两边之和大于第三边
jlewrong
cmpebx,ecx
jeb_equal_c;第一条边等于第二条边
cmpecx,edx
jec_equal_d;第二条边等于第三条边
jmpgeneral;非等腰(等边)三角形
b_equal_c:
cmpecx,edx;继续比较,确认是否为等边三角形
jedengbian
jmpdengyao
c_equal_d:
cmpebx,ecx;继续比较,确认是否为等边三角形
jedengbian
jmpdengyao
;执行至此,能否构成三角形,以及三角形是否等边等腰已经确定,输出
;判断是否为直角三角形
general:
moveax,ebx
imuleax,eax
movsqr,eax
moveax,ecx
imuleax,eax
addsqr,eax
moveax,edx
imuleax,eax
cmpsqr,eax
jezhijiao
jmpxiesanjiao
xiesanjiao:
moveax,offsetmsg_xiesanjiao
calldispmsg
jmplast
zhijiao:
moveax,offsetmsg_zhijiao
calldispmsg
jmplast
dengbian:
moveax,offsetmsg_dengbian
calldispmsg
jmplast
dengyao:
moveax,offsetmsg_dengyao
calldispmsg
jmplast
wrong:
moveax,offsetmsg_wrong
calldispmsg
jmplast
;输出完毕,运行结束
last:
exit0
endstart
4.采用无条件和条件转移指令构造while和dowhile循环结构,完成下面的求和任务并输出sum(sum为双字)。
includeio32.inc
.data
sumdword0
.code
start:
callreaduid
movecx,eax
getsum:
cmpecx,0
jenext
addsum,ecx
dececx
jmpgetsum
next:
moveax,sum
calldispuid
calldispcrlf
exit0
endstart
思考题:
假设sum为双字无符号整数,在和不溢出的情况下求出n的最大值;输出sum和n的值。
includeio32.inc
.data
sumdword0
.code
start:
movecx,1
getsum:
moveax,sum;备份sum的值
addsum,ecx
jcnext;进位的话跳出循环,此时的eax中保存最大sum,而ecx=n+1
incecx
jmpgetsum
next:
calldispuid;输出sum
calldispcrlf
dececx
moveax,ecx;输出n
calldispuid
calldispcrlf
exit0
endstart
5.编写程序,求0到100间所有偶数和并输出。
要求采用loop、while和dowhile三种不同的循环结构完成。
●以下采用loop循环
includeio32.inc
.code
start:
movecx,100
xoreax,eax
again:
addeax,ecx
dececx
loopagain
calldispuid
exit0
endstart
;结果2550
●以下采用while循环
includeio32.inc
.code
start:
movecx,100
xoreax,eax
again:
cmpecx,0
jldone
addeax,ecx
subecx,2
jmpagain
done:
calldispuid
exit0
endstart
;结果2550
●以下采用dowhile循环
includeio32.inc
.code
start:
movecx,100
xoreax,eax
again:
addeax,ecx
subecx,2
cmpecx,0
jldone
jmpagain
done:
calldispuid
exit0
endstart
;结果2550
6.Fibonaccinumbers的定义:
f1=1,f2=1,fn=fn-1+fn-2n>=3
编程输出Fibonaccinumbers的前30项。
includeio32.inc
.data
spacebyte'',0;输出空格
f1dword1;fn-1
f2dword1;fn-2
.code
start:
movecx,30
moveax,f1;输出f1
calldisp
dececx
moveax,f2;输出f2
calldisp
dececx
again:
moveax,f1
addeax,f2;eax=fn-1+fn-2
calldisp
movebx,f2
movf1,ebx;fn-1=fn-2
movf2,eax;fn-2=eax
loopagain
jmpdone
dispproc
pusheax;保护寄存器eax
calldispuid
moveax,offsetspace
calldispmsg
popeax;恢复寄存器eax
ret
dispendp
done:
exit0
endstart
;结果:
;1123581321345589144233377610987159725844181676510946177112
;86574636875025121393196418317811514229832040Pressanykeytocontinue
思考题:
在不产生溢出的情况下n的最大值是多少?
includeio32.inc
.data
spacebyte'',0;输出空格
maxnbyte'TheMaximumnis',0
f1dword1;fn-1
f2dword1;fn-2
.code
start:
xorecx,ecx
moveax,f1;输出f1
calldisp
incecx
moveax,f2;输出f2
calldisp
incecx
again:
moveax,f1
addeax,f2;eax=fn-1+fn-2
jcdone;有进位时跳出
calldisp
movebx,f2
movf1,ebx;fn-1=fn-2
movf2,eax;fn-2=eax
incecx
jmpagain
dispproc;输出过程
pusheax
calldispuid
moveax,offsetspace
calldispmsg
popeax
ret
dispendp
done:
calldispcrlf
moveax,offsetmaxn
calldispmsg
moveax,ecx
calldispuid
calldispcrlf
exit0
endstart
;运行结果:
;1123581321345589144233377610987159725844181676510946177112
;86574636875025121393196418317811514229832040134********30935245785702
;88792274651493035224157817390881696324598610233415516558014126791429643
;3494437701408733113490317018363119032971215073
;TheMaximumnis47
;Pressanykeytocontinue
7.有一个首地址为array的20个有符号的双字数组,编程分别求出正数的和与负数的和并输出。
includeio32.inc
.data
arraydword-1,2,4,-8,6,-4,-9,8,4,0,
-49,4,31,-68,1,-4,6,5,7,-51
sumofposdword?
;保存正数的和
sumofnegdword?
;保存负数的和
.code
start:
movecx,lengthofarray;数组元素个数
xoredx,edx;数组下标
again:
moveax,array[edx*4];取出下标为edx的数组元素
incedx
cmpeax,0
jgpositive
jlnegative
continue:
loopagain
jmpdone;所有求和结束
positive:
addsumofpos,eax;正数求和
jmpcontinue
negative:
addsumofneg,eax;负数求和
jmpcontinue
done:
moveax,sumofpos
calldispsid
calldispcrlf
moveax,sumofneg
calldispsid
calldispcrlf
exit0
endstart
运行结果:
78
-194
思考题:
将求和改为求最大值与最小值。
includeio32.inc
.data
arraydword-1,2,4,-8,6,-4,-9,8,4,0,
-49,4,31,-68,1,-4,6,5,7,-51
maxdword?
;最大值
mindword?
;最小值
.code
start:
moveax,array[0];为max和min赋初值
movmax,eax
movmin,eax
movecx,lengthofarray;数组元素个数
xoredx,edx;数组下标
again:
moveax,array[edx*4];取出下标为edx的数组元素
incedx
cmpeax,max
jg_max
cmpeax,min
jl_min
continue:
loopagain
jmpdone;数组遍历结束
_max:
movmax,eax;保存可能的最大值
jmpcontinue
_min:
movmin,eax;保存可能的最小值
jmpcontinue
done:
moveax,max
calldispsid
calldispcrlf
moveax,min
calldispsid
calldispcrlf
exit0
endstart
运行结果:
31
-68
8.有一个首地址为string的字符串,剔除string中所有的空格字符。
请从字符串最后一个字符开始逐个向前判断、并进行处理。
includeio32.inc
.data
stringbyte'Letushaveatry!
',0;测试字符串
.code
start:
moveax,offsetstring;输出字符串
calldispmsg
calldispcrlf
movesi,lengthofstring;esi为数组长度
decesi;esi指向最后一个元素
again:
moval,string[esi]
cmpal,''
jzreject;剔除空格
decesi
jldone;循环结束
jmpagain
reject:
movecx,esi;ecx指向当前找到的空格
reject1:
;将后续字符依次往前移
moval,string[ecx+1]
movstring[ecx],al
testal,al;遇到\0结尾
jzagain;完成一个空格的剔除
incecx
jmpreject1;继续前移后一个字符
done:
moveax,offsetstring
calldispmsg
calldispcrlf
exit0
endstart
;运行结果:
;Letushaveatry!
;Letushaveatry!
9.有一个首地址为string的字符串,分别统计string中空格、英文字母、数字和其它字符的个数并输出。
includeio32.inc
.data
stringbyte'Letushavaatry.1,2,3,Go!
',0;测试字符串
countofspacedword?
;空格
countofletterdword?
;英文字母
countofdigitdword?
;数字
countofotherdword?
;其他
.code
start:
xoredx,edx;字符数组下标
again:
moval,string[edx]
cmpal,0;遇到\0结束
jzdone
cmpal,'';判断空格
jzspace
cmpal,'a';初步判断为小写字母
jgeletter_lower
continue_upper:
cmpal,'A';初步判断为大写字母
jgeletter_upper
continue_digit:
cmpal,'0';初步判断为数字
jgedigit0
continue_other:
;其他字符
inccountofother
continue:
;增加下标号,开始下一次循环
incedx
jmpagain
space:
inccountofspace
jmpcontinue
letter_lower:
cmpal,'z';进一步判断是否为小写字母
jlelower
jmpcontinue_upper;继续判断是否大写字母
lower:
;确定为小写字母
inccountofletter
jmpcontinue
letter_upper:
cmpal,'Z';进一步判断是否为大写字母
jleupper
jmpcontinue_digit;继续判断是否为数字
upper:
;确定为大写字母
inccountofletter
jmpcontinue
digit0:
cmpal,'9';进一步判断是否数字
jledigit9
jmpcontinue_other;只能是其他字符
digit9:
inccountofdigit
jmpcontinue
;依次输出空格数、英文字母数、数字、其他、
done:
moveax,countofspace
calldispuid
calldispcrlf
moveax,countofletter
calldispuid
calldispcrlf
moveax,countofdigit
calldispuid
calldispcrlf
moveax,countofother
calldispuid
calldispcrlf
exit0
endstart
;运行结果:
;5
;15
;3
;5
10.palindrome(回文)是指正读和反读都一样的数或文本。
例如:
11、121、12321等,编写程序,求10到10000之间所有回文数并输出。
要求每行输出10个数。
提示:
采用div指令把整数分解为单个的数字,并将它们组合成一个新的整数。
includeio32.inc
.data
stringbyte0,0,0,0,0;保存转换后的字符串(逆序方式)
chushudword10;除数10,用于提取个位数字
backdword?
;备份eax寄存器的值
countdword?
;计算以输出的总数,用于每10个换行
.code
start:
moveax,10;eax从10到10000
outlp:
movecx,0;ecx清零,用于记录字符串实际长度
movback,eax;备份eax寄存器的值
DigitToString:
;将数字转换成字符串
xoredx,edx;被除数高32位清零
divchushu;edx保存余数,eax保存商
adddl,30h
movstring[ecx