汇编语言程序设计课程设计.docx
《汇编语言程序设计课程设计.docx》由会员分享,可在线阅读,更多相关《汇编语言程序设计课程设计.docx(11页珍藏版)》请在冰豆网上搜索。
汇编语言程序设计课程设计
一、实验目的
1.熟练掌握call、ret的原理及应用
2.熟练掌握子程序的框架、进行模块化程序设计
3.掌握参数与结果的传递、批量数据传递等问题的解决方法
二、实验内容及要求
(一)综合程序设计:
利用实验10中的三个子程序,将poweridea公司的数据按照下图所示的格式在屏幕上显示出来,要求计算人均收入并显示出来。
poweridea公司的数据如下:
assumecs:
codesg
datasegment
db'1975','1976','1977','1978','1979','1980','1981','1982','1983'
db'1984','1985','1986','1987','1988','1989','1990','1991','1992'
db'1993','1994','1995'
;年份
dd16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
dd345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
;公司总收入
dw3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
dw11542,14430,15257,17800
;公司雇员人数
dataends
tablesegment
db21dup('yearsummne?
?
')
tableends
要求:
(1)给出该设计过程或算法
(2)在代码中必要的地方给出相应注释
(3)最终显示结果。
三、实验解答过程及结果
(1)该题目的第一段db型年份数据是以字符串储存的,不适合后续的操作,所以先用ice子程序把年份数据转化为word型数据。
接下来循环开始,先调用dtoc1子程序,把第一年(1975)的word型年份数据转化为字符串储存在es中,再调用show_str函数在屏幕缓冲区显示出来。
接着调用dtoc2子程序和show_str子程序把第一年的收入在同一行显示出来。
再接着调用dtoc1子程序和show_str子程序把第一年的雇员数在同一行显示出来,最后计算平均收入,同样调用两个子程序显示出来。
不停地循环,循环21次,把所有的数据都显示出来,输入程序结果,程序完结。
(2)代码及数据如下:
assumecs:
codesg
datasegment
db'1975','1976','1977','1978','1979','1980','1981','1982','1983'
db'1984','1985','1986','1987','1988','1989','1990','1991','1992'
db'1993','1994','1995'
;年份
dd16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
dd345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
;公司总收入
dw3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
dw11542,14430,15257,17800
;公司雇员人数
dataends
tablesegment
db21dup('yearsummne?
?
')
tableends
stacksegment
db1024dup(0)
stackends
codesgsegment
start:
movax,data
movds,ax
movax,table
moves,ax
movax,stack
movss,ax
movsp,1024
movsi,0
movbx,0
movdh,5
movax,1975;初始化,dh为输出时的行数
movcx,21
so:
callice
pushax
movax,ds:
[si]
calldtoc1
popax
pushcx
movdl,1
movcl,00000111b
callshow_str
popcx;这两段输出年份
pushax
pushdx
movax,ds:
[si+84]
movdx,ds:
[si+86]
calldtoc2
popdx
popax
pushcx
movdl,8
movcl,00000111b
callshow_str
popcx;这两段输出收入
pushax
movax,ds:
[bx+168]
calldtoc1
popax
pushcx
movdl,18
movcl,00000111b
callshow_str
popcx;这两段输出雇员数
pushax
pushdx
movax,[si+84]
movdx,[si+86]
divwordptrds:
[bx+168]
;计算人均收入,结果为16位,保存在ax中
calldtoc1
popdx
popax
pushcx
movdl,26
movcl,00000111b
callshow_str
popcx;这两段输出平均收入
addsi,4
addbx,2
incdh
incax
loopso;循环21次,增加参数
movax,4c00h
int21h
;名称:
ice
;功能:
在ds:
si开始,以“数据”“0”的格式用新数据替换旧数据(即年份字符串)
;参数:
(ax)=word型的数据,es:
si指向字符串的首地址
;返回:
无
;说明:
把字符串的年份转化为word型数据,并以0结尾,方便dtoc1函数的调用
ice:
pushbx
movds:
[si],ax
movbx,0
movds:
[si+2],bx
popbx
ret
;名称:
dtoc1
;功能:
将一个word型数转化为字符串,数应不大于65535
;参数:
(ax)=word型的数据,es:
si指向字符串的首地址
;返回:
es:
[si]放此字符串,以0结尾
;说明:
因为ds放了数据段,为免混淆,把字符串放在es里,下面的函数也相同
dtoc1:
pushcx
pushbx
pushdx
movdx,0
pushdi
pushsi
movdi,0
cir1:
movcx,10
divcx
adddx,30h
movbx,dx
pushbx
incdi
movdx,0
movcx,ax
jcxzow
jmpshortcir1
ow:
movcx,di
s:
popbx
moves:
[si],bx
incsi
loops
popsi
popdi
popdx
popbx
popcx
ret
;名称:
dtoc2
;功能:
将一个dword型数转化为字符串,数不应大于FFFFFFFFFFFFFFFF
;参数:
(ax)=dword型的数据的低16位,(dx)=dword型的数据的高16位,es:
si指向字符串的首地址
;返回:
es:
[si]放此字符串,以0结尾
dtoc2:
pushcx
pushbx
pushsi
pushdi
movdi,0
cir2:
movcx,10
calldivdw
addcx,30h
movbx,cx
pushbx
incdi
movbx,dx
addbx,ax
movcx,bx
jcxzox
jmpshortcir2
ox:
movcx,di
s8:
popbx
moves:
[si],bx
incsi
loops8
popdi
popsi
popbx
popcx
ret
;名称:
divdw
;功能:
除法,被除数32位,除数16位,商32位,余数16位,不会溢出
;参数:
(dx)=被除数高16位,(ax)=被除数低16位,(cx)=除数
;返回:
(dx)=商高16位,(ax)=商低16位,(cx)=余数
divdw:
pushbx
pushax
movax,dx
movdx,0
divcx
movbx,ax
popax
divcx
movcx,dx
movdx,bx
popbx
ret
;名称:
show_str
;功能:
在指定的位置,用指定的颜色,显示一个用0结束的字符串
;参数:
(dh)=行号(1~25),(dl)=列号(1~80),(cl)=颜色,es:
si指向字符串的首地址
;返回:
无
show_str:
pushdi
pushsi
movdi,0
pushax
pushdx
decdh
decdl;这里采用习惯上的叫法,放在显示缓冲区最开头就是1行1列
moval,160;1行80个字符,一个字符2个字节
muldh
adddl,dl;一个字符2个字节
movdh,0
adddx,ax
adddi,dx;这几行是为了计算字符串首的偏移地址
movah,cl;字符的高位保存属性,低位保存数据
pushcx
change:
movcl,es:
[si]
movch,0
jcxzok
moval,es:
[si]
pushes
pushax
movax,0b800h;显示缓冲区的空间为B8000H~BFFFFH
moves,ax
popax
moves:
[di],ax;输出到缓冲区
popes
incsi
adddi,2
jmpshortchange
ok:
popcx
popdx
popax
popsi
popdi
ret
codesgends
endstart
(3)结果如图:
四、实验总结
通过这次实验,我学会了call和ret指令的用法,学会了编写子程序以及调用各个子程序,组成一个大程序。
我发现,汇编的子程序,就跟c语言的函数差不多。
在实验的过程中,我学会了编写更加复杂的程序,懂得了更多的汇编知识,在汇编语言的学习上又有了新的进步。