汇编实验7.docx
《汇编实验7.docx》由会员分享,可在线阅读,更多相关《汇编实验7.docx(24页珍藏版)》请在冰豆网上搜索。
汇编实验7
山东大学实验报告
2016年月日
姓名刘方铮,学号201411130001系年级计算机科学与技术系2014级
科目汇编语言题目HANOI塔题和查找电话号码phone
实验源程序清单
HANOI塔题hanoi:
DX放messageBX=NCX=XSI=YDI=Z
;**********************************************************************
datareasegment
message1db'n=?
',0ah,0dh,'$'
message2db'nameofA?
',0ah,0dh,'$'
message3db'nameofB?
',0ah,0dh,'$'
message4db'nameofC?
',0ah,0dh,'$'
flagdw0’’;标志位
constantdw10000,1000,100,10,1;识别位数
datareaends
;**********************************************************************
;**********************************************************************
prognamsegment
mainprocfar
assumecs:
prognam,ds:
datarea
;------------------------------------------------------
start:
pushds
subax,ax
pushax
movax,datarea
movds,ax
leadx,message1;输出message1
movah,09h
int21h
calldecibin;调用十进制转二进制并将N输入BX
callcrlf调用回车
cmpbx,0
jzexit
leadx,message2;输出message2
movah,09
int21h
movah,01h
int21h
movah,0
movcx,ax;读取X的名存入CX
callcrlf
leadx,message3;输出message3
movah,09
int21h
movah,01h;读Y输入SI
int21h
movah,0
movsi,ax
callcrlf
leadx,message4;显示message4
movah,09
int21h
movah,01h
int21h
movah,0
movdi,ax;读Z入DI
callcrlf
callhanoi;调用递归算法
exit:
ret
mainendp
;---------------------------------------------------------
hanoiprocnear
cmpbx,1;bx与1
jebasis;等于跳转basis
callsave;调用存储功能
decbx;bx-1
xchgsi,di;交换si,di
callhanoi;调用递归
callrestor;恢复NXYZ?
callprint;显示XNZ
decbx;bx-1
xchgcx,si;交换cx,si
callhanoi;调用递归
jmpreturn;跳转return
basis:
callprint
return:
ret
hanoiendp
;-------------------------------------------------------------
printprocnear;输出显示模块
movdx,cx
movah,02h
int21h
callbinidec;调用二进制转十进制
movdx,di
movah,02h
int21h
callcrlf
ret
printendp
;----------------------------------------------------------------
saveprocnear;存储模块
popbp
pushbx
pushcx
pushsi
pushdi
pushbp
ret
saveendp
;------------------------------------------------------------------
restorprocnear;恢复模块
popbp;出栈
popdi
popsi
popcx
popbx
pushbp
ret
restorendp
;--------------------------------------------------------------------
decibinprocnear;键盘输入十进制,保存在bx中
movbx,0
newchar:
movah,1
int21h;键盘输入一个字符,将其对应的ASCII码输入到al中
subal,30h
jlexit1
cmpal,9d
jgexit1
cbw
xchgax,bx
movcx,10d
mulcx
xchgax,bx
addbx,ax
jmpnewchar
exit1:
ret
decibinendp
;--------------------------------------------------------------------
binidecprocnear
pushbx
pushcx
pushsi
pushdi
movflag,0
movcx,5
leasi,constant
dec_div:
movax,bx
movdx,0
divwordptr[si]
movbx,dx
movdl,al
cmpflag,0
jnzprint1
cmpdl,0
jeskip
movflag,1
print1:
adddl,30h
movah,02h
int21h
skip:
addsi,2
loopdec_div
popdi
popsi
popcx
popbx
ret
binidecendp
;--------------------------------------------------------------------
crlfprocnear
movdl,0ah
movah,02h
int21h
movdl,0dh
movah,02h
int21h
ret
crlfendp
;**********************************************************************
prognamends
;**********************************************************************
endstart
查找电话号码phone:
(一)实验目的:
学习用汇编语言设计与编写子程序,理解子程序的调用过程。
(二)实验要求:
(1)要求程序建立一个可存放50项的电话号码表,每项包括人名(20个字符)及电话号码(8个字符)两部分;
(2)程序可接收输入人名及相应的电话号码,并把它们加入电话号码表中;
(3)凡有新的输入后,程序应按人名对电话号码表重新排序;
(4)程序可接收需要查找电话号码的人名,并从电话号码表中查出其电话号码,再在屏幕上以如下格式显示出来。
nametel.
XXXXXXXX
;*****************************************************************8
data_segsegment
namcountdw0;thenumbercount
tel_tabdb50dup(28dup(''));thetelbook
nameitemlabelbyte;storename
max1db21
ncurlendb?
nameflddb21dup(?
)
phoneitemlabelbyte;storenumer
max2db9
pcurlendb?
phoneflddb9dup(?
)
addenddw?
;排序时的tel_tab尾地址指针
namtempdb28dup(?
),13,10,'$'
swapdb0;排序中是否有交换的标志位
msg_countdb'Doyouwanttoinsertaitemtophonebook?
(Y/N)',13,10,'$'
msg_errordb'Error!
Pleaseentertherequested...',13,10,'$'
msg_inputnamdb'Inputname:
','$'
msg_inputnumdb'Inputatelephonenumber:
','$'
msg_inquiredb'Doyouwantatelephonenumber?
(Y/N)','$'
msg_snamedb'name?
',13,10,'$'
msg_outtitledb'nametel.',13,10,'$'
msg_nomatchdb'NOtEXIT!
',13,10,'$'
msg_allphonedb'printallRECORD?
(Y/N)',13,10,'$'
msg_resultdb'nametel.',13,10,'$'
data_segends
;**********************************************************************
stack_segsegmentparastack'stack';定义堆栈段
dw256dup(0)
stack_segends
;*********************************************************************
code_segsegment
;----------------------------------------------------------------------------
mainprocfar
assumecs:
code_seg,ds:
data_seg,es:
data_seg,ss:
stack_seg
start:
movax,data_seg
movds,ax;初始化数据段
moves,ax;初始化附加段
xorbx,bx
cld;将标志寄存器Flag的方向标志位DF清零
leadi,tel_tab;名字表的首地址放入di
a1:
leadx,msg_count
movah,9
int21h;显示信息是否插入一项纪录?
(Y/N)'
movah,1
int21h
movbl,al
callcrlf
cmpbl,'n';判断输入
jza2
cmpbl,'N'
jza2
cmpbl,'y'
jznext0
cmpbl,'Y'
jznext0
movah,9
leadx,msg_error;b;非显示错误提示信息
int21h
jmpa1;返回a1
next0:
leadx,msg_inputnam
movah,9
int21h;要求输入名字
callinput_name;调用input_name输入人名
callstor_name;调用stor_name存储人名
callinput_phone;调用input_phone输入电话
callname_sort;排序
jmpa1;是否继续输入?
a2:
leadx,msg_inquire
movah,9
int21h;显示是否查找电话号码
movah,1
int21h
movbl,al
callcrlf
cmpbl,'n';判断输入
cmpbl,'N'
jza3
cmpbl,'y'
jznext1
cmpbl,'Y'
jznext1
movah,9
leadx,msg_error;非显示输入错误信息
int21h
jmpa2
next1:
leadx,msg_sname
movah,9
int21h;显示要查询电话的姓名
callinput_name;输入姓名
callname_search
jmpa2
a3:
leadx,msg_allphone;显示所有电话号码
movah,9
int21h
movah,1
int21h
movbl,al
callcrlf;回车换行
cmpbl,'n'
jzexit
cmpbl,'N'
jzexit
cmpbl,'y'
jznext2
cmpbl,'Y'
jznext2
movah,9
leadx,msg_error
int21h
jmpa3
next2:
callprintline;调用子程序打印出所有的电话号码
exit:
ret
mainendp
;---------------------------------------------------------------------
input_nameprocnear;子程序接受输入字符
leadx,nameitem
movah,0ah
int21h
callcrlf;回车换行
movbh,0
movbl,ncurlen
movcx,21
subcx,bx
repeat1:
movnamefld[bx],20h
incbx
looprepeat1;输入的名字为20字节,不足的用空格补足
ret
input_nameendp
;-------------------------------------------------------------------------
stor_nameprocnear;子程序传送名字的每个字母到si
incnamcount
cld
leasi,namefld
movcx,20
repmovsb
ret
stor_nameendp
;----------------------------------------------------------------------------
input_phoneprocnear;子程序(输入电话号码)
leadx,msg_inputnum
movah,9
int21h;显示要求输入电话号码
leadx,phoneitem
movah,10
int21h
movbh,0
movbl,pcurlen
movcx,9
subcx,bx
repeat2:
movphonefld[bx],20h
incbx
looprepeat2
callcrlf
cld
leasi,phonefld
movcx,8
repmovsb;把输入的号码存入namtab表中
ret
input_phoneendp
;----------------------------------------------------------
name_sortprocnear;子程序
pushdi
pushax
pushbx
cmpnamcount,1
jzexit4;比较名字个数是否为一个
s1:
movswap,0
subdi,56
movaddend,di
leasi,tel_tab
s2:
movcx,20
movdi,si
adddi,28
movax,di
movbx,si
repecmpsb
jbes3
callexchange
s3:
movsi,ax
cmpsi,addend
jbes2
cmpswap,0;如果有交换,继续下一趟
jnzs1
exit4:
popbx
popax
popdi
ret
name_sortendp
;--------------------------------------------------------------------
exchangeprocnear;交换tel_tab中di,si所指表项的内容
movcx,28
leadi,namtemp
movsi,bx
repmovsb
movcx,28
movdi,bx
repmovsb
movcx,28
leasi,namtemp
repmovsb
movswap,1
ret
exchangeendp
;----------------------------------------------------------
name_searchprocnear;查找输入的名字
leadi,tel_tab
pushdi
movbx,namcount
loop1:
leasi,namefld
movcx,20
repecmpsb;连续查找匹配名字
jefound;找到跳转found
popdi;没找到di出栈
adddi,28
pushdi
decbx
jnzloop1
leadx,msg_nomatch
movah,9
int21h;没有找到输出信息
found:
popdi
leadx,msg_outtitle
movah,9
int21h
movsi,di
leadi,namtemp
movcx,28
repmovsb
leadx,namtemp
movah,9
int21h;显示查到的姓名和电话号码
ret
name_searchendp
;-------------------------------------------------------
printlineprocnear;输出排序结果
pushdi
pushnamcount
callcrlf;回车换行
leadx,msg_result
movah,9
int21h;显示升序输出姓名、电话
leasi,tel_tab
loop2:
leadi,namtemp
movcx,28
repmovsb
leadx,namtemp
movah,9
int21h;显示姓名、电话
decnamcount
jnzloop2;循环输出
popnamcount
popdi
ret
printlineendp
;---------------------------------------------------------
crlfprocnear;回车换行
movdl,0dh
movah,2
int21h
movdl,0ah
movah,2
int21h
ret
crlfendp
;---------------------------------------------------------
code_segends
endmain
模块层次图:
各程序模块介绍:
流程图如下:
编译及运行结果
问题及收获
本次实验初步了解了子程序的设计,是程序设计模块化,这对于设计较复杂的程序是非常重要的。
实验对字符串的处理,要求相对较高,涉及字符串的移动和比较,此外还应该注意在定义缓冲区长度时,应把回车的长度加入进去,否则可能会造成覆盖的错误。
实验过程中对于si和di的使用,由于没有及时保存发生了,越界错误,后经仔细调试才发现问题,汇编程序设计中压栈操作时十分重要的,在设计程序时应引起注意,注意一些公用寄存器的值的保存的问题。
通过这次实验,我发现了使用子过程能更清晰的设计程序,相信这对我今后汇编语言的学习会起到很重要的作用。