实验2.4查找电话号码 1.目:查找电话号码 phone 2.实求 (1) 要求建立一个可存放5的

文章正文
发布时间:2024-12-26 03:58

1.题目:查找电话号码phone
2.实验要求:
(1)建立一个可存放50项的电话号码表,每项包括任命(20个字符)及电话号码(8个字符)两部分;
(2)程序可接收输入人名及相应的电话号码,并把它们加入电话号码表中;
(3)凡有新的输入后,程序应按照人名对电话号码表重新排序;
(4)程序可接收需要查找电话号码的人名,并从电话号码表中查出其电话号码,再在屏幕上以如下格式显示出来。

name tel.
××× ×××
3.提示:程序采用子程序结构。主程序的部分主要如下:

显示提示符‘Input name’
调用子程序’input_name’接收人名
调用子程序stor_name把人名存入电话号码表tel_tab中
显示提示符’Input a telephone number:’
调用子程序inphone接收电话号码,并把它存入电话号码表tel_tab中
如果输入已经结束,则调用name_sort子程序对电话号码表按人名排序
显示提示符’Do you want a telephone number?’
回答N则退出程序
回答Y则再显示提示符‘name?’
调用子程序input_name接收人名
调用子程序name_search再电话号码表中查询所需的电话号码
调用子程序printline按要求格式显示人名和电话号码
重复查号提示符直至用户不再要求查找为止

思路

大致画了以下流程图,并指明了主程序和子程序相互传递参数之间的方式

在这里插入图片描述


程序较为复杂,设计到了串转移和串查找指令,程序的核心功能是name_sort排序和name_search查找功能。name_sort使用了冒泡排序,但又不是经典的冒泡排序,为了程序简单,每次都从头到尾开始比较,把原本的比较次数(N)*(N-1)变为了N * N,并设置交换位swapped来判断是否结束排序。name_search要用到cmpsw指令,找到后把他放入temp临时变量中之后传递给Printline,没找到通过cx=-1传递给print_line。
以下是name_sort 和 name_search的空间地址结构:

在这里插入图片描述


还有一个坑就是在定义缓冲区长度时应该把回车的长度加进去,否则可能造成覆盖的错误。

在这里插入图片描述


总体来说,程序极为麻烦,调试极其不易。

代码 ;--------数据段开始---------- datasg segment namepar label byte ;接受名字输入 maxnlen db 21 actnlen db ? _name db 21 dup(?) phonepar label byte ;接受电话号码输入 maxplen db 9 actplen db ? phone db 9 dup(?) crlf db 13,10,'$' ;回车换行 endaddr dw ? mess1 db 'Input name:','$' mess2 db 'Input a telephone number:','$' mess3 db 'Do you want a telephone number:','$' mess4 db 'name?','$' mess5 db 'name',16 dup(' '),'tel',0dh,0ah,'$' mess6 db 'Not in the table.',0dh,0ah,'$' mess7 db 'Invalid input!',0dh,0ah,'$' count db 0 tel_tab db 50 dup(20 dup(' ')),8 dup(' ') ;电话号码表 temp db 20 dup(' '),8 dup(' '),0dh,0ah,'$' ;暂存的tel_tab项 swapped db 0 datasg ends ;--------代码段开始--------- codesg segment main proc far assume cs:codesg,ds:datasg,es:datasg start: push ds sub ax,ax push ax mov ax,datasg mov ds,ax mov es,ax ;;;;;;;;;;;;;;; cld ;方向标志位置0 lea di,tel_tab ;目的变址指针指向tel_tab,为了之后搬入tel_tab inputloop: mov ah,09h ;提示'Input name' lea dx,mess1 int 21h call input_name cmp actnlen,0 ;输入长度小于1,都将直接终止输入 jz a10 cmp count,50 ;如果超过50个号码 je a10 call stor_name mov ah,09h ;提示'Input a telephone number' lea dx,mess2 int 21h call inphone jmp inputloop a10: cmp count,1 jbe searchloop ;count<=1 直接跳去查找 call name_sort ;否则就要排序 searchloop: lea dx,mess3 ;提示‘Do you want a telephone number:’ mov ah,09 int 21h mov ah,01h ;输入字符判断y or n int 21h cmp al,'N' je exit cmp al,'n' je exit cmp al,'Y' je showname cmp al,'y' je showname mov ah,09 ;回车换行 lea dx,crlf int 21h lea dx,mess7 ;如果不是Yes or No 否则提示'Invalid input!'' mov ah,09 int 21h jmp searchloop ;反复询问 showname: mov ah,09 ;回车换行 lea dx,crlf int 21h lea dx,mess4 ;提示'name?'' mov ah,09 int 21h call input_name call name_search call printline jmp searchloop ;反复询问 exit: ret main endp ;-------input_name子程序开始----- ;这里不需要保护寄存器,采用直接地址法传递参数 input_name proc near mov ah,0ah ;调用0a号中断输入到缓冲区 lea dx,namepar ;ds:dx 为缓冲区首地址 int 21h mov ah,02h ;换行 mov dl,0ah int 21h mov bh,0 mov bl,actnlen ;bx存放name的长度 mov cx,20 sub cx,bx ;cx剩余长度 i20: ;填充空格字段 mov _name[bx],20h inc bx loop i20 ret input_name endp ;---------stor_name子程序开始------- ;这里不需要保护寄存器,采用直接地址法传递参数 stor_name proc near inc count cld lea si,_name ;将20个字节的name搬入tel_phone mov cx,10 rep movsw ret stor_name endp ;----------inphone子程序开始-------- ;这里不需要保护寄存器,采用直接地址法传递参数 inphone proc near mov ah,0ah ;调用0a号中断输入到缓冲区 lea dx,phonepar ;ds:dx 为缓冲区首地址 int 21h mov ah,02h ;换行 mov dl,0ah int 21h mov bh,0 mov bl,actplen mov cx,9 sub cx,bx is20: ;填充空格字段 mov phone[bx],20h inc bx loop is20 cld ;清理方向标志位 lea si,phone ;将8位phone搬入tel_phone mov cx,4 rep movsw ret inphone endp ;--------name_sort子程序开始-------- ;这里不需要保护寄存器,采用直接地址法传递参数 ;冒泡排序 name_sort proc near sub di,56 ;tel_lab 20 + 8 mov endaddr,di ;endaddr指向最后第二个tel_lab项的首地址 ns10: mov swapped,0 ;没有交换过 lea si,tel_tab ;si指向tel_lab的首地址 ns20: mov cx,20 ;20个长度的name mov di,si add di,28 mov ax,di mov bx,si repe cmpsb jbe ns30 ;如果tel_tab[i]<tel_tab[i+1] 不用交换 call npxchg ns30: mov si,ax cmp si,endaddr ;一轮比较后,最大的已经排到了最后面 jbe ns20 cmp swapped,0 ;如果交换过,则需要再次比较 ; mov di,endaddr ;endaddr - 28 代表最后一个已经比较完成 ; sub di,28 ; mov endaddr,di jnz ns10 ret name_sort endp ;;;;;;;;;;;;;;;;;;;; ;bx 和 ax 寄存器传递参数u ;tel_tab[i]和tel_tab[i+1]交换 npxchg proc near mov cx,14 ;temp = a[i] lea di,temp mov si,bx rep movsw mov cx,14 ;a[i+1] = a[i] mov di,bx rep movsw mov cx,14 ;a[i] = temp lea si,temp rep movsw mov swapped,1 ;swapped ret npxchg endp ;--------name_search子程序开始----- name_search proc near lea si,tel_tab ;源变址指针si ->tel_tab mov bx,si add endaddr,28 nase10: lea di,_name ;目的变址指针di ->_name mov cx,10 ;name长度20 db repe cmpsw jcxz nase_exit ;如果找到 add bx,28 ;si+28 ,并用bx暂存 mov si,bx cmp si,endaddr ;比较是否查到末尾了 jbe nase10 ;还未到最后一个则继续查找 notintab: mov cx,-1 ;没有找到让cx=-1 ret nase_exit: mov si,bx ;则搬入temp lea di,temp mov cx,14 rep movsw ret name_search endp ;-------printline子程序开始---- printline proc near cmp cx,-1 je norecord ;没有找到 mov ah,09h ;提示'name',16 dup(' '),'tel',0dh,0ah,'$' 标题栏 lea dx,mess5 int 21h mov ah,09h lea dx,temp ;输入暂存temp的tel_tab项 int 21h ret norecord: mov ah,09h ;提示'Not in the table.' lea dx,mess6 int 21h ret printline endp codesg ends end start 结果

在这里插入图片描述

首页
评论
分享
Top