查找电话号码.docx
- 文档编号:11495175
- 上传时间:2023-03-02
- 格式:DOCX
- 页数:16
- 大小:31.74KB
查找电话号码.docx
《查找电话号码.docx》由会员分享,可在线阅读,更多相关《查找电话号码.docx(16页珍藏版)》请在冰豆网上搜索。
查找电话号码
一、实验目的与要求
学习用汇编语言设计与编写子程序。
题目:
查找电话号码phone
二、实验内容
(1)要求程序建立一个可存放50项的电话号码表,每项包括人名(20个字符)及电
话号码(8个字符)两部分;
(2)程序可接收输入人名及相应的电话号码,并把它们加入电话号码表中;
(3)凡有新的输入后,程序应按人名对电话号码表重新排序;
(4)程序可接收需要查找电话号码的人名,并从电话号码表中查出其电话号码,
再在屏幕上以如下格式显示出来。
nametel.
XXXXXXXX
三、实验步骤
1.设计分析
1)根据题目要求必须要定义的空间:
✧可存50个联系人的号码表
✧姓名缓冲区
✧号码缓冲区
✧各种提示字符串
2)为操作方便,多定义以下空间:
✧tab_len用来记录联系人数目
✧endaddr用来记录最后一个联系人的地址+28
✧temp一个联系人记录的大小,用于排序时的缓存数据
2.
程序执行流程图
3.模块层次图
4.模块说明
模块名
输入
输出
功能
main总控制模块
用户的各种操作选择
如选择是否继续插入,继续查询等
各种提示信息,如提示输入姓名、号码、提示是否继续操作
建立联系人号码表,对号码表人名排序,提供查询、显示功能
input_name
联系人的姓名到tname缓冲区
无
读入姓名到tname缓冲区并把不满20位部分补空格
name_search
tname缓冲区的姓名
查找结果放在bx寄存器
在号码表查找tname缓冲区的姓名,找到则bx存放该记录的地址,否则(bx)=-1
crlf
无
回车换行
输出回车换行
stor_name
tname缓冲区的姓名
把tname缓冲区的姓名移动到号码表,对应记录数tab_len增1,endaddr增28
把姓名从缓冲区移动到号码表
inphone
电话号码
把inphone缓冲区的号码移动到号码表中
读入电话号码并转存到号码表中
name_sort
从tab_len取出记录数,从endaddr取出最后一个记录地址。
号码表中只有最后一个记录无序,前面记录有序
排序
对号码表进行排序(用插入排序,每次输入一个联系人后进行排序)
print_all
号码表的地址
无
显示号码表中的所有电话号码
printline
要显示的联系人地址存放在bx
无
显示单个联系人的信息
四、实验总结与体会。
Ø先画好程序框图和模块调用图,并在编码中不断修改完善,对把握程序的整体结构很有帮助。
Ø把模块设计成子程序在主程序调用,分解了整个程序功能,降低了设计的难度,同时方便调试和修改。
Ø程序中添加适当的辅助变量,可以简化操作,如本程序设表长tab_len和endaddr(电话表最后一个基址)方便排序、插入等操作。
Ø程序需要良好的人机交互,应该有各种操作提示和警告信息。
Ø程序中输入输出等要有容错处理,要能对各种可能情况作出反应。
Ø使用跳转指令时应注意跳转是否超出范围,Jmp指令能够实现无条件远转移,但je,jb等条件转移指令只能段内短转移,如有需要可以跳转到一个地方再用jmp跳转。
Ø使用循环结构时不要忘记了结束条件,导致死循环。
Ø因为汇编接近机器语言,直接对内存操作,所以脑中要有内存单元,单元地址等的清晰概念和形象,对数据在内存中表示、各种寻址方式、各寄存器的用途、用法都应该相当熟悉。
Ø汇编语言没有像其他高级语言的数据类型的概念,数据都是以二进制存储。
Ø通过这个综合设计,对寄存器的默认组合、使用,常用指令,各种寻址方式基本能够熟练运用。
Ø个人感觉汇编与其他高级语言的操作上的区别:
汇编语言把每一步操作都细化。
所以写起来比较麻烦些,但只有想不到,没有做不到的,只要想的出来的,汇编应该都可以写出来。
Ø程序调试主要是用debug。
Debug是个十分好用的工具,通过设置断点,可以调试任意程序任意部分,通过单步执行可以十分清楚各寄存器和地址单元的变化来找出错误。
五、源程序
datasegment
tel_tabdb50dup(28dup(''));tel_tab电话本空间
tab_lendw0;已存联系人数目
endaddrdw0;最后一个联系人的地址+28
tnamedb21,?
20dup(''),?
;姓名缓冲区
tphonedb9,?
8dup(''),?
;号码缓冲区
tempdb28dup(?
);一个联系人的临时空间
inamedb13,10,'Inputname:
',13,10,'$'
iphonedb13,10,'Inputatelephonenumber:
',13,10,'$'
go_ondb13,10,'Continueinsert?
snamedb13,10,'Name?
',13,10,'$'
name_edb13,10,13,10,'Thenamehasbeeninthetable!
Pleaseinputagain!
',13,10,'$'
text2db13,10,'NameTel.',13,10,'$'
text3db13,10,'Thenameisnotinthetelephonetable!
',13,10,'$'
text4db13,10,13,10,'Doyouwantatelephonenumber?
dataends
codesegment
;****************************************************************************
;主程序
;-------------------------------------------------------------------------------------
mainprocfar
assumecs:
code,ds:
data,es:
data
start:
pushds;保存旧数据用于返回
subax,ax
pushax
movax,data;数据段、附加段初始化
movds,ax
moves,ax
inname:
leadx,iname;提示输入姓名
movah,09h
int21h
callinput_name;调用读入姓名子程序
callname_search;调用查找子程序,
cmpbx,-1;如表中不存在该联系人
jestor;则跳转到stor
callcrlf;回车换行
leadx,name_e;否则提示该联系人已在表中,提示重新输入
movah,09h
int21h
jmpinname
stor:
callstor_name;调用姓名转存子程序,把姓名移动到表中
leadx,iphone;提示输入电话号码
movah,09h
int21h
callinphone;调用读入号码子程序
callname_sort;排序
callcrlf
leadx,go_on;提示是否继续插入
movah,09h
int21h
choice1:
movah,07;读取用户选择
int21h
cmpal,'y'
jeinname
cmpal,'Y'
jeinname
cmpal,'n'
jeprint_all;如选择不插入,则显示所有记录
cmpal,'N'
jeprint_all
jmpchoice1
print_all:
callprintall;显示所有记录
want_search:
callcrlf
leadx,text4;提示是否查找号码
movah,09
int21h
callcrlf
choice2:
movah,07;读取用户选择
int21h
cmpal,'y'
jesearch;如果为y或Y则跳转到查找search
cmpal,'Y'
jesearch
cmpal,'n';为n或N则退出程序
jeexit_m
cmpal,'N'
jeexit_m
jmpchoice2
search:
leadx,sname;提示用户输入要查找的姓名
movah,09
int21h
callinput_name;读入姓名
callname_search;查找
callcrlf
callcrlf
cmpbx,-1;是否查找到?
jenot_find;(bx)=1则跳转到未找到not_find
leadx,text2;找到则输出'NameTel.'
movah,09
int21h
callprintline;显示查找到的联系人
jmpwant_search;跳转到提示查找
not_find:
;未找到
callcrlf
leadx,text3;输出'Thenameisnotinthetelephonetable!
'
movah,09h
int21h
jmpwant_search
exit_m:
ret
printallprocnear
;**************************************************************************
;显示所有电话。
显示电话表中的所有姓名和号码,查看排序结果是否正确
;----------------------------------------------------------------------------------------------
callcrlf
callcrlf
leadx,text2;输出'NameTel.'
movah,09
int21h
leabx,tel_tab;号码表基址
rept1:
callprintline;显示联系人
addbx,28;求下一个联系人首地址
cmpbx,endaddr;是否到达表尾?
jbrept1;未到达则继续显示
ret
printallendp
;*******************************************************************
;输入姓名子程序:
读入姓名到tname缓冲区,并把不满20位的部分
;补上空格(方便查找时的比较)
;----------------------------------------------------------------------------------
input_nameprocnear
callcrlf
noinputn:
leadx,tname;姓名缓冲区
movah,0ah;调用dos0ah读入字符串功能
int21h
cmptname[1],0;如果输入为回车
jenoinputn;继续等待输入
xorbx,bx
movbl,tname[1]
movcx,20
subcx,bx
set_blank:
movtname[bx+2],20h;把不满20位的部分补空格
incbx
loopset_blank
callcrlf
ret
input_nameendp
;*****************************************************************
;stor_name,该子程序把tname缓冲区的姓名转存入号码表中
;---------------------------------------------------------------------------------
stor_nameprocnear
xorcx,cx
movcl,tname[1];字符个数
leasi,tname[2]
movdi,endaddr
cld
repmovsb
inctab_len;联系人人数增1
addendaddr,28;最后一个联系人地址增28
ret
stor_nameendp
;***************************************************************
;获取号码子程序:
读入用户输入的号码到tphone缓冲区,然后
;转存入号码表对应位置
;------------------------------------------------------------------------------------
inphoneprocnear
noinputp:
callcrlf
leadx,tphone
movah,0ah
int21h;调用dos0a号功能输入字符串
cmptphone[1],0;判断输入是否为回车
jenoinputp;是,则继续等待输入
xorcx,cx
movcl,tphone[1]
leasi,tphone[2]
movdi,endaddr
subdi,8;待插入位置
cld
repmovsb;移动
ret
inphoneendp
;**********************************************************************
;排序子程序(用直接插入排序),对号码表进行按人名从小到大排序
;--------------------------------------------------------------------------------------------------
name_sortprocnear
cmp[tab_len],1;记录数1,不用排序
jeexitn
leadi,tel_tab;第一个记录地址
movsi,endaddr
subsi,28;最后一个记录-待排序记录的地址
next1:
movcx,20
movax,si;暂存两个地址
movdx,di
cld
repecmpsb;查找插入位置
jbinsert
movsi,ax
movdi,dx
adddi,28;比较下一个
cmpdi,si;是否比较完
jbnext1;没有则继续比较
jmpexitn;否则排序完成
insert:
movcx,28
movsi,ax
leadi,temp
repmovsb;待排序数据放到缓冲区
movdi,ax
next2:
movcx,28
movsi,di
subsi,28
repmovsb;记录后移
subdi,56
cmpdi,dx
janext2
movcx,28
movdi,dx
leasi,temp
repmovsb;插入到待插位置
exitn:
ret
name_sortendp
;******************************************************************************
;姓名查找子程序。
入口参数为tname缓冲区的人名,用寄存器bx返回结果,找到则返回该
;姓名对应记录的地址,未找到则返回(bx)=-1
;-------------------------------------------------------------------------------------------------------------------
name_searchprocnear
cmptab_len,0;记录为0,无法查找
jeexit_nofind
leasi,tname[2];待查姓名地址
movax,si;暂存si
leabx,tel_tab;从第一个记录开始查找
rsearch:
movcx,20
movdi,bx
repecmpsb
jzexit_n
movsi,ax
addbx,28;查找下一个
cmpbx,endaddr
jbrsearch
exit_nofind:
movbx,-1;未找到则(bx)=-1
exit_n:
ret
name_searchendp
;******************************************************************************
;显示姓名和电话子程序。
待显示的记录的地址保存在bx寄存器。
;-----------------------------------------------------------------------------------------
printlineprocnear
pushax;保存ax
callcrlf
xorsi,si
movcx,28;共28个字符
movah,02h;调用dos2号显示字符功能
nextc:
movdl,[bx][si];待显示字符
int21h
incsi;输出下一个字符
loopnextc
callcrlf
popax
ret
printlineendp
;******************************************************************************
;回车换行子程序
;-----------------------------------------------------------------------------------------
crlfprocnear
pushax
pushdx
movah,02h
movdl,0dh;回车
int21h
movdl,0ah;换行
int21h
popdx
popax
ret
crlfendp
;-----------------------------------------------------------------------------------------
mainendp;主程序结束
codeends;代码段结束
endstart;程序结束
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 查找 电话号码