查找电话号码

发布时间:2018-06-30 02:36:43   来源:文档文库   
字号:

一、 实验目的与要求

学习用汇编语言设计与编写子程序。

题目:查找电话号码phone

二、 实验内容

(1) 要求程序建立一个可存放50项的电话号码表,每项包括人名(20个字符)及电

话号码(8个字符)两部分;

(2) 程序可接收输入人名及相应的电话号码,并把它们加入电话号码表中;

(3) 凡有新的输入后,程序应按人名对电话号码表重新排序;

(4) 程序可接收需要查找电话号码的人名,并从电话号码表中查出其电话号码,

再在屏幕上以如下格式显示出来。

name tel

X X X X X X X X

三、 实验步骤

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_len1endaddr28

把姓名从缓冲区移动到号码表

inphone

电话号码

inphone缓冲区的号码移动到号码表中

读入电话号码并转存到号码表中

name_sort

tab_len取出记录数,从endaddr取出最后一个记录地址。号码表中只有最后一个记录无序,前面记录有序

排序

对号码表进行排序(用插入排序,每次输入一个联系人后进行排序)

print_all

号码表的地址

显示号码表中的所有电话号码

printline

要显示的联系人地址存放在bx

显示单个联系人的信息

四、 实验总结与体会

先画好程序框图和模块调用图,并在编码中不断修改完善,对把握程序的整体结构很有帮助

把模块设计成子程序在主程序调用,分解了整个程序功能,降低了设计的难度,同时方便调试和修改

程序中添加适当的辅助变量,可以简化操作,如本程序设表长tab_len endaddr(电话表最后一个基址)方便排序、插入等操作。

程序需要良好的人机交互,应该有各种操作提示和警告信息

程序中输入输出等要有容错处理,要能对各种可能情况作出反应

使用跳转指令时应注意跳转是否超出范围,Jmp指令能够实现无条件远转移,但jejb等条件转移指令只能段内短转移,如有需要可以跳转到一个地方再用jmp跳转。

使用循环结构时不要忘记了结束条件,导致死循环。

因为汇编接近机器语言,直接对内存操作,所以脑中要有内存单元,单元地址等的清晰概念和形象,对数据在内存中表示、各种寻址方式、各寄存器的用途、用法都应该相当熟悉。

汇编语言没有像其他高级语言的数据类型的概念,数据都是以二进制存储。

通过这个综合设计,对寄存器的默认组合、使用,常用指令,各种寻址方式基本能够熟练运用

个人感觉汇编其他高级语言的操作上的区别:汇编语言把每一步操作都细化所以写起来比较麻烦些,但只有想不到,没有做不到的,只要想的出来的,汇编应该都可以写出来。

程序调试主要是用debugDebug是个十分好用的工具,通过设置断点,可以调试任意程序任意部分,通过单步执行可以十分清楚各寄存器和地址单元的变化来找出错误。

五、 源程序

data segment

tel_tab db 50 dup( 28 dup(' ')) ; tel_tab电话本空间

tab_len dw 0 ; 已存联系人数目

endaddr dw 0 ; 最后一个联系人的地址+28

tname db 21,?,20 dup(' '),? ; 姓名缓冲区

tphone db 9,?,8 dup(' '),? ; 号码缓冲区

temp db 28 dup(?) ; 一个联系人的临时空间

iname db 13,10,'Input name:',13,10,'$'

iphone db 13,10,'Input a telephone number:',13,10,'$'

go_on db 13,10,'Continue insert? ',13,10,'$'; 提示是否继续插入联系人

sname db 13,10,'Name?',13,10,'$'

name_e db 13,10,13,10,'The name has been in the table! Please input again!',13,10,'$'

text2 db 13,10,'Name Tel. ',13,10,'$'

text3 db 13,10,'The name is not in the telephone table!',13,10,'$'

text4 db 13,10,13,10,'Do you want a telephone number? ',13,10,'$'

data ends

code segment

; ****************************************************************************

; 主程序

; -------------------------------------------------------------------------------------

main proc far

assume cs:code ,ds:data,es:data

start:

push ds ; 保存旧数据用于返回

sub ax,ax

push ax

mov ax,data ; 数据段、附加段初始化

mov ds,ax

mov es,ax

inname: lea dx,iname ; 提示输入姓名

mov ah,09h

int 21h

call input_name ; 调用读入姓名子程序

call name_search ; 调用查找子程序,

cmp bx,-1 ; 如表中不存在该联系人

je stor ; 则跳转到stor

call crlf ; 回车换行

lea dx,name_e ; 否则提示该联系人已在表中,提示重新输入

mov ah,09h

int 21h

jmp inname

stor: call stor_name ; 调用姓名转存子程序,把姓名移动到表中

lea dx,iphone ; 提示输入电话号码

mov ah,09h

int 21h

call inphone ; 调用读入号码子程序

call name_sort ; 排序

call crlf

lea dx,go_on ; 提示是否继续插入

mov ah,09h

int 21h

choice1: mov ah,07 ; 读取用户选择

int 21h

cmp al,'y'

je inname

cmp al,'Y'

je inname

cmp al,'n'

je print_all ; 如选择不插入,则显示所有记录

cmp al,'N'

je print_all

jmp choice1

print_all: call printall ; 显示所有记录

want_search: call crlf

lea dx,text4 ; 提示是否查找号码

mov ah,09

int 21h

call crlf

choice2: mov ah,07 ; 读取用户选择

int 21h

cmp al,'y'

je search ; 如果为yY则跳转到查找search

cmp al,'Y'

je search

cmp al,'n' ; nN则退出程序

je exit_m

cmp al,'N'

je exit_m

jmp choice2

search: lea dx,sname ; 提示用户输入要查找的姓名

mov ah,09

int 21h

call input_name ; 读入姓名

call name_search ; 查找

call crlf

call crlf

cmp bx,-1 ; 是否查找到?

je not_find ; (bx)=1 则跳转到未找到not_find

lea dx,text2 ; 找到则输出 'Name Tel. '

mov ah,09

int 21h

call printline ; 显示查找到的联系人

jmp want_search ; 跳转到提示查找

not_find: ; 未找到

call crlf

lea dx,text3 ;输出 'The name is not in the telephone table!'

mov ah,09h

int 21h

jmp want_search

exit_m: ret

printall proc near

;**************************************************************************

;显示所有电话。显示电话表中的所有姓名和号码,查看排序结果是否正确

;----------------------------------------------------------------------------------------------

call crlf

call crlf

lea dx,text2 ; 输出'Name Tel. '

mov ah,09

int 21h

lea bx,tel_tab ; 号码表基址

rept1: call printline ; 显示联系人

add bx,28 ; 下一个联系人首地址

cmp bx,endaddr ; 是否到达表尾?

jb rept1 ; 未到达则继续显示

ret

printall endp

;*******************************************************************

;输入姓名子程序:读入姓名到tname缓冲区,并把不满20位的部分

;补上空格(方便查找时的比较)

;----------------------------------------------------------------------------------

input_name proc near

call crlf

noinputn: lea dx,tname ; 姓名缓冲区

mov ah,0ah ; 调用dos 0ah读入字符串功能

int 21h

cmp tname[1],0 ; 如果输入为回车

je noinputn ; 继续等待输入

xor bx,bx

mov bl,tname[1]

mov cx,20

sub cx,bx

set_blank: mov tname[bx+2],20h ; 把不满20位的部分补空格

inc bx

loop set_blank

call crlf

ret

input_name endp

;*****************************************************************

;stor_name,该子程序把tname缓冲区的姓名转存入号码表中

;---------------------------------------------------------------------------------

stor_name proc near

xor cx,cx

mov cl,tname[1] ;字符个数

lea si,tname[2]

mov di,endaddr

cld

rep movsb

inc tab_len ;联系人人数增1

add endaddr,28 ;最后一个联系人地址增28

ret

stor_name endp

;***************************************************************

;获取号码子程序:读入用户输入的号码到tphone缓冲区,然后

;转存入号码表对应位置

;------------------------------------------------------------------------------------

inphone proc near

noinputp: call crlf

lea dx,tphone

mov ah,0ah

int 21h ;调用dos 0a号功能输入字符串

cmp tphone[1],0 ;判断输入是否为回车

je noinputp ;是,则继续等待输入

xor cx,cx

mov cl,tphone[1]

lea si,tphone[2]

mov di,endaddr

sub di,8 ;待插入位置

cld

rep movsb ;移动

ret

inphone endp

;**********************************************************************

;排序子程序(用直接插入排序),对号码表进行按人名从小到大排序

;--------------------------------------------------------------------------------------------------

name_sort proc near

cmp [tab_len],1 ;记录数1,不用排序

je exitn

lea di,tel_tab ;第一个记录地址

mov si,endaddr

sub si,28 ;最后一个记录-待排序记录的地址

next1: mov cx,20

mov ax,si ;暂存两个地址

mov dx,di

cld

repe cmpsb ;查找插入位置

jb insert

mov si,ax

mov di,dx

add di,28 ;比较下一个

cmp di,si ;是否比较完

jb next1 ;没有则继续比较

jmp exitn ;否则排序完成

insert:

mov cx,28

mov si,ax

lea di,temp

rep movsb ;待排序数据放到缓冲区

mov di,ax

next2: mov cx,28

mov si,di

sub si,28

rep movsb ;记录后移

sub di,56

cmp di,dx

ja next2

mov cx,28

mov di,dx

lea si,temp

rep movsb ;插入到待插位置

exitn: ret

name_sort endp

;******************************************************************************

;姓名查找子程序。入口参数为tname缓冲区的人名,用寄存器bx返回结果,找到则返回该

;姓名对应记录的地址,未找到则返回(bx)=-1

;-------------------------------------------------------------------------------------------------------------------

name_search proc near

cmp tab_len,0 ; 记录为0,无法查找

je exit_nofind

lea si,tname[2] ; 待查姓名地址

mov ax,si ; 暂存si

lea bx,tel_tab ; 从第一个记录开始查找

rsearch: mov cx,20

mov di,bx

repe cmpsb

jz exit_n

mov si,ax

add bx,28 ; 查找下一个

cmp bx,endaddr

jb rsearch

exit_nofind: mov bx,-1 ;未找到则(bx=-1

exit_n: ret

name_search endp

;******************************************************************************

;显示姓名和电话子程序 。待显示的记录的地址保存在bx寄存器。

;-----------------------------------------------------------------------------------------

printline proc near

push ax ;保存ax

call crlf

xor si,si

mov cx,28 ;28个字符

mov ah,02h ;调用dos 2 号显示字符功能

nextc: mov dl,[bx][si] ;待显示字符

int 21h

inc si ;输出下一个字符

loop nextc

call crlf

pop ax

ret

printline endp

;******************* ***********************************************************

;回车换行子程序

;-----------------------------------------------------------------------------------------

crlf proc near

push ax

push dx

mov ah,02h

mov dl,0dh ; 回车

int 21h

mov dl,0ah ; 换行

int 21h

pop dx

pop ax

ret

crlf endp

;-----------------------------------------------------------------------------------------

main endp ; 主程序结束

code ends ; 代码段结束

end start ; 程序结束

本文来源:https://www.2haoxitong.net/k/doc/dc5c913e5727a5e9856a6117.html

《查找电话号码.doc》
将本文的Word文档下载到电脑,方便收藏和打印
推荐度:
点击下载文档

文档为doc格式