1.题目:查找电话号码phone
2.实验要求:
(1)建立一个可存放50项的电话号码表,每项包括任命(20个字符)及电话号码(8个字符)两部分;
(2)程序可接收输入人名及相应的电话号码,并把它们加入电话号码表中;
(3)凡有新的输入后,程序应按照人名对电话号码表重新排序;
(4)程序可接收需要查找电话号码的人名,并从电话号码表中查出其电话号码,再在屏幕上以如下格式显示出来。
name tel.
××× ×××
3.结构
input_name
接收从键盘输入的名字,并将其存入结构体namin中;
stor_name
将结构体namin中的名字存入临时电话表项单元temp_tab的前20字节;
inphone
接收从键盘输入的电话号码,并将其存入结构体phonein中,然后再从此结构体重将电话号码存入临时电话表项单元temp_tab的23号位置开始的8字节;
name_sort
根据名字对电话表项中的项进行排序(其实是向已经排好序的电话表项中插入一项到合适的位置)。首先找到插入位置并存入cx中,然后调用insert将其插入。
insert
根据插入位置(cx中存储着插入位置),从电话表项的最后一项开始,前一项复制到后一项直至到达插入位置,然后将si指向temp_tab,di指向插入位置,进行插入;
name_search
首先将结构体namin中的名字存入单元temp_nam,然后将si指向该单元,然后使di指向电话表项tel_tab,循环比较,如果找到,将位置存入cx,如果没有找到,令cx为0;
printline
首先需要输出“name tel.”,然后换行再根据cx中的位置输出对应名字和电话号码。
clear
清空临时单元temp_nam和tel_tab中的内容;
crlf
在终端打印换行和回车;
代码如下
;***************************************************************************
datarea segment ;define data segment
mess1 db 'Input name:',13,10,'$'
mess2 db 'Input a telephone number:',13,10,'$'
mess3 db 'Do you want a telephone number?(Y/N)',13,10,'$'
mess4 db 'name?',13,10,'$'
mess5 db 'name',19 dup(0),'tel.',13,10,'$'
mess6 db 'Not find!',13,10,'$'
num dw 0 ;用来标识电话表中数据个数
;yonin label byte
;max db 1
;act db ?
;yon db 1 dup(?)
phonein label byte
pmax db 8
pact db ?
phone db 8 dup(?)
namin label byte
nmax db 20
nact db ?
nam db 20 dup(?)
temp_nam db 20 dup(?)
temp_tab db 20 dup(?),4 dup(?),8 dup(?),13,10,'$'
;排序用,临时储存tel_tab中的一项
tel_tab db 50 dup(20 dup(?),4 dup(?),8 dup(?),13,10,'$')
;每一项35(20+8+4+3)字节
datarea ends
;***************************************************************************
prognam segment ;define code segment
;---------------------------------------------------------------------------
main proc far
assume cs:prognam,ds:datarea,es:datarea
start: ;starting execution address
;set up stack for return
push ds ;save old data segment
sub ax,ax ;put zero in AX
push ax ;save it on stack
;set DS register to current data segment
mov ax,datarea ;datarea segment addr
mov ds,ax ; into DS register
mov es,ax ; into ES register
;MAIN PART OF PROGRAM GOES HERE
begin:
mov ah,09
lea dx,mess1 ;提示输入名字
int 21h
call clear
call input_name ;输入名字
cmp nact,0
je search ;如果没有输入名字,表明输入结束,开始排序、查询
call stor_name ;存储名字到对应单元
mov ah,09
lea dx,mess2 ;提示输入电话号码
int 21h
call inphone ;输入电话号码并存储到对应单元
call name_sort ;开始按照名字排序
jmp begin ;继续输入
search:
mov ah,09
lea dx,mess3 ;提示是否进行查询
int 21h
mov ah,01
int 21h
cmp al,'N'
je exit
call crlf
mov ah,09
lea dx,mess4 ;提示输入名字以进行查询
int 21h
call input_name ;输入名字
cmp nact,0
je exit
call name_search ;查询
call printline ;输出
jmp search ;
exit:
ret ;return to DOS
main endp ;end of main part of program
;---------------------------------------------------------------------------
;接收从键盘的输入名字,存储到存储单元namin
input_name proc near
mov ah,0ah
lea dx,namin
int 21h
call crlf
ret
input_name endp
;---------------------------------------------------------------------------
;从存储单元nam的姓名存储到临时表项temp_tab
stor_name proc near
cmp nact,0
je exit1
lea si,nam
lea di,temp_tab
sub ch,ch
mov cl,nact
cld
rep movsb
exit1:
ret
stor_name endp
;---------------------------------------------------------------------------
;接收键盘输入的电话号码,并存储到phonein,然后在存储到临时表项temp_tab
inphone proc near
mov ah,0ah
lea dx,phonein
int 21h
cmp pact,0
je exit2
call crlf
lea si,phone
lea di,temp_tab
add di,23
sub ch,ch
mov cl,pact
cld
rep movsb
exit2:
ret
inphone endp
;---------------------------------------------------------------------------
;根据名字进行排序,首先找到插入位置,然后从最后一个表项开始前面的一个表项复制到
;后面的表项,到达插入位置后,将临时表项(temp_tab)中的内容复制到对应位置
name_sort proc near
cmp num,0
jnz sort
lea si,temp_tab ;如果表项中没有内容,直接插入
lea di,tel_tab
mov cx,35
cld
repz movsb
jmp exit3
sort: ;否则,进行排序
mov cx,num
lea di,tel_tab
lea si,temp_tab
loopsort:
push di
push cx
mov cx,20
repz cmpsb
ja move ;如果>0,则使si指向下一个表项,继续循环
pop cx
pop di
call insert ;如果<=0,则进行插入(cx中保存要插入的“位置”)
jmp exit3 ;插入结束,退出
move:
pop cx
pop di
add di,35 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
lea si,temp_tab
loop loopsort
mov cx,35 ;正常退出循环,说明需要插入在最后
rep movsb
exit3:
inc num ;表项个数加1
ret
name_sort endp;;;;;;;;;;;;此处,没有正确返回,因为push进去没有pop出来
;---------------------------------------------------------------------------
;进入此子程序后,cx存储着需要移动的表项个数,从后往前进行复制(移动)
insert proc near
mov ax,num ;num-cx+1是位置,cx是需要移动的表项个数
loopinsert:
push ax
mov bx,35
mul bx
lea di,tel_tab ;di=tel_tab+ax*31
add di,ax ;si=di-31
mov si,di
sub si,35
push cx
mov cx,35
rep movsb
pop cx
pop ax
dec ax
loop loopinsert
lea si,temp_tab ;si=temp_tab
lea di,tel_tab ;di=tel_tab+ax*31
mov bx,35
mul bx
add di,ax
mov cx,35
rep movsb
ret
insert endp
;---------------------------------------------------------------------------
name_search proc near
call clear
mov ch,0
mov cl,nact
lea si,nam ;si=nam;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
lea di,temp_nam ;需要清空temp_nam
rep movsb
mov cx,num
lea di,tel_tab
lea si,temp_nam
loopfind:
push di
push cx
mov ch,0
mov cl,20
repz cmpsb
je find
pop cx
pop di
add di,35
lea si,temp_nam
loop loopfind
mov cx,0
jmp exit4
find:
pop cx
pop di
exit4:
ret
name_search endp
;---------------------------------------------------------------------------
printline proc near
cmp cx,0
jnz next
mov ah,09
lea dx,mess6 ;提示未找到
int 21h
jmp exit5
next:
lea dx,mess5
mov ah,09
int 21h
mov ax,num
sub ax,cx
mov bx,35
mul bx
lea dx,tel_tab
add dx,ax
mov ah,09
int 21h
exit5:
ret
printline endp
;---------------------------------------------------------------------------
crlf proc near
mov dl,0ah
mov ah,02h
int 21h
mov dl,0ah
mov ah,02h
int 21h
ret
crlf endp
;---------------------------------------------------------------------------
clear proc near
lea di,temp_tab
xor al,al
mov cx,32
rep stosb
lea di,temp_nam
xor al,al
mov cx,20
rep stosb
ret
clear endp
;---------------------------------------------------------------------------
prognam ends ;end of code segment
;***************************************************************************
end start ;end assembly