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