微机原理程序题教学资料.docx
《微机原理程序题教学资料.docx》由会员分享,可在线阅读,更多相关《微机原理程序题教学资料.docx(28页珍藏版)》请在冰豆网上搜索。
微机原理程序题教学资料
微机原理程序题
1.将下面C语言程序的代码片段转换为功能等价的汇编语言代码片段,其中sign与sinteger
均为双字变量。
if(sinteger==0)
sign==0;
elseIf(siteger>0)
sign=1;
else
sign=-1;
moveax,sinteger
movedx,sign
cmpeax,0
jnzL1
movebx,0
L1:
cmpebx,0
jlL2
movebx,1
L2:
movebx,-1
2.将下面C语言程序的代码片段转换为功能等价的汇编语言代码片段,其中ch1与caps均为字节变量。
if(ch1>=’a’&&ch1<=’z’)
caps==0;
if(ch1>=’A’&&ch1<=’Z’)
caps==1;
movax,ch1
movbx,caps
cmpax,a
jbnext
cmpax,z
janext
movbx,0
next:
cmpax,A
jldone
cmpax,Z
jadone
done:
3.将下面C语言程序的代码片段转换为功能等价的汇编语言代码片段,其中sum与i变量均为双字变量。
sum=0;
for(i=1;i<=100;i++)
if(i%2==0)
sum=sum+i;
movecx,i
movecx,1
.while(ecx<=100)
moveax,ecx
xoredx,edx
movebx,2
divebx
cmpedx,0
jnznext
addsum,ecx
next:
incecx
.endw
1.能被4整除但不能被100整除,或者年被400整除的年份是闰年。
编程写一个完整的程序,求出2012年~2099年中的所有闰年年份,并把它们存放在数组Lyear中。
算法描述
;esi=0;ecx=2012;
;while(ecx<2100)
;{if(yearmod4=0andyearmod100<>0)or(yearmod400=0)then
;{Lyear[esi]=ecx;esi++;}
;ecx++;
;}
;Lcounter=esi;
includeio32.inc
.data
Lyeardword100dup(?
)
Lcounterdword0
.code
mainproc
xoresi,esi;esi闰年个数计数器,兼做Lyear下标。
movecx,2012;ecx年份计数器。
.while(ecx<2100)
moveax,ecx
xoredx,edx
movebx,400
divebx
cmpedx,0
jzleap;ifyearmod400=0thengotoleap
moveax,ecx
xoredx,edx
movebx,4
divebx
cmpedx,0
jnznext;ifyearmod4<>0thengotonext
moveax,ecx
xoredx,edx
movebx,100
divebx
cmpedx,0
jznext;ifyearmod100=0thengotonext
leap:
movLyear[esi*4],ecx
incesi
moveax,ecx
calldispuid;输出,用于验证。
可以删掉
calldispcrlf;输出,用于验证。
可以删掉
next:
incecx
.endw
movLcounter,esi
moveax,esi
calldispuid;输出,用于验证。
可以删掉
calldispcrlf;输出,用于验证。
可以删掉
ret
mainendp;endofmain
endmain;endofassembly
2.编程写一个完整的程序,求出2~100之间的所有素数,并将它们存入Prime数组中,素数
的个数存入变量Pcounter中。
;采用伪代码pseudocode描述算法
;1.i=2to100do
;1.1ifiisprimenumberthenprinti
;细化1.1如下:
;1.1j=2toi/2do
;1.1.1ifimodj=0thengotonexti
;1.1.2printi
;合理分配寄存器,i=ebx,j=ecx,edxeax做被除数,ecx做除数.
includeio32.inc
.data
msgbyte'Listofprimenumber',13,10,0
msg1byte'Lcounteris:
',13,10,0
blankbyte'',0
primedword100dup(?
)
pcounterdword0
.code
mainproc;主程序开始
movesi,0
moveax,offsetmsg
calldispmsg
movebx,2
iLoop:
cmpebx,100;i循环入口
jadone
movecx,ebx
shrecx,1;j=i/2
jLoop:
cmpecx,2;j循环入口
jbprint
moveax,ebx
cdq;xoredx,edx
divecx;被除数送eax,32位除法
oredx,edx;cmpedx,0
jznexti;ifimodj=0thengotonexti
dececx
jmpjLoop
print:
movprime[esi*4],ebx
incesi
moveax,ebx
moveax,offsetblank
calldispmsg;显示空格
nexti:
incebx;i=i+1
jmpiLoop
done:
calldispcrlf
moveax,offsetmsg1
calldispmsg
movpcounter,esi
moveax,esi
calldispuid
calldispcrlf
ret;返回操作系统
mainendp;主程序结束
endmain;endofassembly
3.编程写一个完整的程序,将数组aray中的元素按逆序存放,要求程序中附加的变量最少。
数据段的定义如下:
.data
araydword12,4,168,122,-33,56,78,99,345,66,-5
;采用伪代码pseudocode描述算法
;1.i=n-1downto1do
;1.1j=0toi-1
;1.1.1ifa[j]>a[j+1]thenswap
;合理分配寄存器,i=ecx,j=edx,i-1=ecx-1
includeio32.inc
.data;setdatasegment
blank3byte3dup(20h),0
arraydword12,4,-168,122,33,56,78,99,345,-66,-5
charbyte?
msgbyte13,10,'pressanykeytocontinue...',0;字符串
.code
mainproc
movecx,(lengthofarray)-1;计数循环的初值
iLoop:
;i循环入口
dececx;ecx=i-1
xoredx,edx
jLoop:
;j循环入口,循环控制变量edx
cmpedx,ecx
jgnexti
moveax,array[edx*4]
cmpeax,array[edx*4+4]
jgenextj
xchgeax,array[edx*4+4]
movarray[edx*4],eax
nextj:
incedx
jmpjLoop
nexti:
incecx;retrieveecx
loopiLoop
print:
xorecx,ecx
again:
cmpecx,lengthofarray-1
jgdone
moveax,array[ecx*4]
calldispsid
moveax,offsetblank3;显示空格
calldispmsg
incecx
jmpagain
done:
moveax,offsetmsg;显示:
pressanykeytocontinue
calldispmsg
moveax,offsetchar;暂停,等待按任意键
callreadc
ret;返回操作系统
mainendp
endmain;endofassembly
4.编程写一个完整的程序,求数组aray中的最大值与最小值,并将它们分别存入max和min元中。
数据段的定义如下:
.data
araydword12,4,-168,122,-33,56,78,99,345,-66,-5
mindword?
maxdword?
includeio32.inc
.data
araydword12,4,-168,122,-33,56,78,99,345,-66,-5
mindword?
maxdword?
promptbyte'Enteranintegers:
',0
maxStrbyte'max=%d',13,10,0;显示字符串的格式描述串
minStrbyte'min=%d',13,10,0
.code
mainproc
movecx,lengthofara-1
moveax,ara[0];eax:
max
movebx,eax;ebx,min
movesi,1
again:
cmpeax,ara[esi*4]
jgesmall
moveax,ara[esi*4]
small:
cmpebx,ara[esi*4]
jlenext
movebx,ara[esi*4]
next:
incesi
loopagain
movmax,eax
movmin,ebx
ret;返回操作系统
mainendp
endmain
5.编程写一个完整的程序统计msg中的空格的个数与小写字母的个数,并分别将它们存入space单元与char单元中。
数据段的定义如下:
.data
msgbyte'IloveXUT!
',13,10,0
spacedword?
chardword?
includeio32.inc
.data
msgbyte'IloveXUT!
',13,10,0
spacedword?
chardword?
.code
mainproc
movebx,0
xoredi,edi
movesi,edi
l1:
moval,msg[ebx]
cmpal,20h
jnzdone1
cmpal,0
jznext
incedi
incebx
jmpl1
done1:
cmpal,'a'
jbdone2
cmpal,'z'
jadone2
cmpal,0
jznext
incesi
incebx
jmpl1
done2:
cmpal,0
jznext
incebx
jmpl1
next:
movspace,edi
moveax,space
calldispuid
calldispcrlf
movchar,esi
moveax,char
calldispuid
calldispcrlf
ret
mainendp
endmain
6.编程写一个完整的程序,将字符串msg中所有的小写字母转换为大写字母。
数据段的定义如下:
.data
msgbyte'IloveXUT!
',13,10,0
includeio32.inc
.data
msgbyte'IloveXUT!
',13,10,0
.code
mainproc
movebx,0
l1:
moval,msg[ebx]
cmpal,'a'
jbdone
cmpal,'z'
jadone
subal,20h
done:
cmpal,0
jzdone1
incebx
calldispc
jmpl1
done1:
ret
mainendp
endmain
7.array是一无符号数数组,数据段的定义如下。
要求:
编程写一个完整的程序求出数组元
素中偶数的和,并将它存入esum单元中。
.data
arraydword12,34,123,78,43,234,79,86,98,20
esumdword?
算法描述:
;1.esum=0;
;2.fori=0ton-1do
;ifa[i]isevennunberthenesum=esum+a[i];
;判断偶数,采用test指令测试最低位。
;合理分配寄存器:
采用loop循环,ecx=lengthofarrayesum=eax=0,esi=0,做下标,采用带比例因子的相对寻址处理数组。
includeio32.inc
.data
arraydword12,34,123,78,43,234,79,86,98,20
esumdword?
fmtStrbyte'esum=%d',13,10,0;格式描述串
.code
mainproc
movecx,lengthofarray
xoreax,eax;esum=eax=0
movesi,eax;数组下标
again:
movebx,array[esi*4]
testebx,1
jnznext;ifa[i]isevennunberthenesum=esum+a[i];
addeax,ebx;注意:
转换成汇编语言时,测试的是不是偶数时则取下一个数测试。
next:
incesi
loopagain
movesum,eax
invokeprintf,offsetfmtStr,esum
ret;returntoWindows
mainendp;endofmain
endmain;endofassembly
8.“回文串”是一个正读和反读都一样的字符串,比如“eye”、“level”、“noon”等
。
请写一个程序测试一字符串是否是“回文”,是“回文”则显示“Y”,否则显示“N”。
显示一个字符的子程序为:
dispc,入口参数:
AL=要显示个字符的SACII码。
;算法描述:
;left,right分别指向串的第一个和最后一个元素,采用首尾比较。
;1.left=0,right=n-1,flag='Y';
;2.whileleft;ifa[left++]<>a[right--]then
;{flag='N';break;}
;3.printfflag
;合理分配寄存器:
left=esi,right=edi,flag=al='Y'
includeio32.inc
.data
msgbyte'level',0
countequlengthofmsg
.code
mainproc
movesi,0;left指针
movedi,count-2;right指针,串长不包括结束标志0
moval,'Y';flag=al='Y'
.while(esi两个内存变量不能比较!
movah,msg[esi];left=esi
cmpah,msg[edi];right=edi
jenext
moval,'N'
jmpdisplay
next:
incesi;移动指针指向下一个元素
decedi;移动指针指向下一个元素
.endw
display:
calldispc
calldispcrlf
ret;returntoWindows
mainendp;endofmain
endmain;endofassembly
9.回文是指正读和反读都一样的数或文本。
例如:
11、121、12321等,编写程序,求10到10000之间所有回文数并输出。
显示一个无符号数的子程序为:
dispuid,入口参数:
EAX=要显示无符号数的值。
includeio32.inc
.data
blankbyte'',0
charbyte?
anykeybyte13,10,'pressanykeytocontinue...',0
.code
mainproc
movecx,10
movebx,ecx
.repeat
xoresi,esi
moveax,ecx
.while(eax>0)
xoredx,edx
divebx
imulesi,10
addesi,edx
.endw
cmpesi,ecx
jnenext
moveax,ecx
calldispuid
calldispcrlf
next:
incecx
.until(ecx>10000)
ret
mainendp
endmain
10.编程写一个名为Prime的子程序,用于测试一个整数是否是素数,主子程序间的参数传递通过堆栈完成。
调用Prime子程序求出2~100之间的所有素数,并将它们存入Parray数组中,素数的个数存入变量Pcounter中。
;采用伪代码pseudocode描述算法
;1.i=2to100do
;1.1ifprime(i)thenprinti
;构造函数prime(i):
;ifiisprimenumberthenprime(i)=1elseprime(i)=0
;合理分配寄存器,i=ebx,j=ecx,edxeax做被除数,ecx做除数.
includeio32.inc
.data
msgbyte'Listofprimenumber',13,10,0
msg1byte'pcounteris:
',13,10,0
blankbyte'',0
anyKeybyte13,10,'pressanykeytocontinue...',13,10,0
parraydword100dup(?
)
pcounterdword0
.code
mainproc;主程序开始
movesi,0
moveax,offsetmsg
calldispmsg
movebx,2;i循环的初值
.while(ebx<=100);i循环入口
pushebx;pushparameteronstack参数进栈
callprime
testeax,eax
jznext
l1:
movparray[esi*4],ebx
incesi
moveax,ebx
calldispuid;输出,用于验证。
可以删掉
moveax,offsetblank
calldispmsg
next:
incebx
.endw
calldispcrlf
moveax,offsetmsg1
calldispmsg
movpcounter,esi
moveax,esi
calldispuid
calldispcrlf
ret;返回操作系统
mainendp;主程序结束
;function:
判断一个无符号整数i是否是素数
;Receives:
从栈获取无符号整数i
;Returns:
ifiisprimenumbertheneax=1elseeax=0
;采用伪代码pseudocode描述算法
;1j=2toi/2do
;1.1ifimodj=0then{eax=0return}
;2eax=1;return
;合理分配寄存器,j=ecx,edxeax做被除数,ecx做除数.
primeproc
pushebp;saveebp
movebp,esp
pushecx
pushedx
pushedi
pushesi;save,ecx,edx,edi,esi
movesi,[ebp+8];getparameteri
movedi,esi
shresi,1;esi=i/2
movecx,2;j循环入口
.while(ecx<=esi)
moveax,edi
xoredx,edx;edx=0
divecx;被除数送eax,32位除法
oredx,edx;cmpedx,0
jzretZero;ifimodj=0theneax=0
incecx
.endw
moveax,1;i是否是素数eax=1
jmprestoreReg
retZero:
moveax,0
restoreReg:
popesi
popedi
popedx
popecx