;**********************电话号码表实现*******************************
;在本次试验中需要注意基址寄存器BX的移动方法,对以字为单位的数组,BX的移动方式
;是每移动一次加2或者减2
;另外函数调用的过程中需要小心PUSH和pop的调用是否安全,例如在name_sort中pop CX的
;时候没有先Push CX,导致了name_sort函数不可以调用
;此程序使用比较高效的方法只是对号码单的首地址进行排序,为此开辟了一个地址数组
;AdTable,类似C语言中的指针数组
;在每个名字的前面存有每个名字的长度,有利于对名字进行比较,体现了空间换时间
;程序调试难度较大,费时2天长度,长度349行
;12月7日于海韵
;==================================================================
DateArea segment
TemplateName db 20,?,20 dup(?)
TemplateNumber db 9,?,9 dup(?)
PhoneTable db 50 dup ( 21 dup (?), 8 dup (?) ,'$')
AdTable dw 50 dup (?)
FindedAdress dw 1 dup (?)
InputNamePrint db 13,10,'Input name:','$'
InputNumPrint db 13,10,'Input a telephone number:','$'
AskForNumPrint db 13,10,'Do you want a telepment numbre:(Y/N)','$'
NamePrint db 13,10,'name?','$'
AnswerFindedPrint db 13,10,'name',16 dup (20h),'tel.',13,10,'$'
AnswerNoFindPrint db 13,10,'NO SUCH NAME!','$'
DateArea ends
;=====================================================================
CodeArea segment
assume cs:CodeArea ,ds:DateArea ,es:DateArea
;-----------------------------
main proc far
push ds
sub ax,ax
push ax
mov ax,DateArea
mov ds,ax
mov es,ax
;
mov bx,0
lea si,PhoneTable
Start:
lea dx , InputNamePrint
mov ah,09h
int 21h
;
lea di,AdTable
mov AdTable[bx],si
call input_name;该函数还要返回输入字母为终止时候的提示,
;可以返回一个寄存器的状态来表示
jz Search
call stor_name
;
lea dx, InputNumPrint
mov ah ,09h
int 21h
;
call inphone
;
add si,30
add bx ,2
jmp Start
Search:
;lea dx, AskForNumPrint
;mov ah,09h
;int 21h
call name_sort
lea dx, AskForNumPrint
mov ah,09h
int 21h
;
mov ah,1
int 21h
sub al,4Eh
;
jz Exit
;
lea dx,NamePrint
mov ah,09h
int 21h
;
call input_name
;
call name_search
;
call printline
;
jmp Search
Exit: ret
main endp
;------------------------------
input_name proc near
push ax
push bx
push cx
push dx
push si
push di
;
lea dx,TemplateName
mov ah,0ah
int 21h
lea di ,TemplateName
add di,1
mov al,[di]
cmp al,0
;
pop di
pop si
pop dx
pop cx
pop bx
pop ax
;
ret
input_name endp
;------------------------------
stor_name proc near
push ax
push bx
push cx
push dx
push si
push di
;
mov di,AdTable[bx]
lea si,TemplateName
add si,1
mov dx,21
mov cl,[si]
mov al,cl
cbw
mov cx,ax
inc cx
sub dx,cx
cld
repnz movsb
mov cx,dx
cld
mov al ,20h
repnz stosb
;
pop di
pop si
pop dx
pop cx
pop bx
pop ax
;
ret
;
stor_name endp
;------------------------------
inphone proc near
push ax
push bx
push cx
push dx
push si
push di
;
lea dx,TemplateNumber
mov ah,0ah
int 21h
;
mov di,AdTable[bx]
add di,21
lea si,TemplateNumber
add si,1
mov cl,[si]
mov al,cl
cbw
mov cx,ax
add si,1
cld
repnz movsb
;
pop di
pop si
pop dx
pop cx
pop bx
pop ax
;
ret
inphone endp
;------------------------------
name_sort proc near
push ax
push bx
push cx
push dx
push si
push di
lea dx, AskForNumPrint
mov ah,09h
int 21h
mov cx,bx
OuterSort:
mov bx,0
InnerSort:
mov si,AdTable[bx]
add bx,2
mov di ,AdTable[bx]
mov al,[si]
mov dl,[di]
cmp al,dl
push cx
jg AxGrBx
mov al,dl
cbw
mov cx,ax
jmp PassAGB
AxGrBx:
cbw
mov cx,ax
PassAGB:
add si ,1
add di ,1
cld
repz cmpsb
pop cx
jb Belower
mov ax,AdTable[bx]
sub bx,2
mov dx,AdTable[bx]
xchg ax,dx
mov AdTable[bx],dx
add bx,2
mov AdTable[bx],ax
Belower:
mov ax,bx
add ax,2
cmp ax,cx
jnz InnerSort
sub cx,2
cmp cx,2
jnz OuterSort
pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
name_sort endp
;------------------------------
name_search proc near
push ax
push bx
push cx
push dx
push si
push di
mov ax,bx
mov bx ,0
mLoop:
lea si,TemplateName+1
mov cl,[si]
push ax
mov al,cl
cbw
mov cx,ax
add cx,1
pop ax
mov di,AdTable[bx]
cld
repz cmpsb
jz FindOutNum
add bx, 2
cmp bx ,ax
jz FindNoNum
jmp mLoop
FindNoNum:
pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
FindOutNum:
mov dx,AdTable[bx]
add dx,1
mov FindedAdress,dx
;mov ah,09h
; int 21h
pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
name_search endp
;------------------------------
printline proc near
push ax
push bx
push cx
push dx
push si
push di
jz NoFind
lea dx,AnswerFindedPrint
mov ah,09
int 21h
mov dx,[FindedAdress]
mov ah,09h
int 21h
JMP RetPlace
NoFind:
lea dx,AnswerNoFindPrint
mov ah,09h
int 21h
RetPlace:
pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
printline endp
;------------------------------
CodeArea ends
end main