?? 1.asm
字號:
DATAS SEGMENT
namcount dw 0 ;存入名字的個數
tel_tab db 50 dup(28 dup(' ')) ;表格
nameitem label byte
nmax db 21
ncurlen db ?
namefld db 21 dup(?) ;姓名緩存區
phoneitem label byte
pmax db 9
pcurlen db ?
phonefld db 9 dup(?) ;電話號碼緩存區
addend dw ? ;排序時的tel_tab尾地址指針
namtemp db 28 dup(?),13,10,'$' ;臨時保存表中一項
swap db 0 ;排序中是否有交換的標志位
msg_count db 'Please enter the order you want to input?',13,10,'$'
msg_illcount db 'Error:The order of your enter exceed the limit of 50! Plesae input the number again!',13,10,'$'
msg_illch db 'Error:The order of your enter is illegal! Please intput the number again!',13,10,'$'
msg_inputnam db 'Input name:','$'
msg_inputerr db 'Error:Input error!,please input a name!',13,10,'$'
msg_inputnum db 'Input a telephone number:','$'
msg_inquire db 'Do you want to find a telephone number?(Y/N)','$'
msg_sname db 'name?',13,10,'$'
msg_outtitle db 'name tel.',13,10,'$'
msg_nomatch db 'No such name!Do you want to insert this item(Y/N)?',13,10,'$'
msg_result db 'The Phone Dictionary is listed as follows:',13,10,'$'
DATAS ENDS
;-----------------------------------------------------------------------------------------------------------
STACKS SEGMENT para stack 'stack'
dw 256 dup(0)
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,ES:DATAS,SS:STACKS
main proc far ;主程序段
START:
MOV AX,DATAS
MOV DS,AX
MOV ES,AX ;初始化附加段
cld ;df=0
lea di,tel_tab ;名字表的首地址放入di
lea dx,msg_count
mov ah,9
int 21h
again:call decibin ;調用decibin
cmp dx,2
call crlf
je exit1 ;一個有效字符都沒輸入,跳轉要求重新輸入.輸入的為非法字符即非數字則不等輸入完就跳出
push bx
cmp bx,50 ;
ja return ;輸入的個數大于50出錯跳出
repeat0:
pop bx
cmp namcount,bx ;目前項數和要求輸入的項數比較,名字數和bx比較
je choice ;如果所有項都輸入完畢則跳到choice排序
push bx ;stor_name會用到bx,先保存
lea dx,msg_inputnam
mov ah,9
int 21h ;要求輸入名字
call input_name ;調用input_name
cmp ncurlen,0 ;沒有輸入了則開始排序,輸入名字的字符數為0跳轉
je choice
call stor_name
call input_phone ;調用input_phone
jmp repeat0 ;由于tel_tab是順序連續存儲,每一次輸入一項后,di即指向下一項的開始,所以無需調整
choice:cmp namcount,1
jb return1 ;表中項數小于1則要求輸入
call name_sort ;不小于調用name_sort
rotate:lea dx,msg_inquire ;輸出'Do you want to find a telephone number?(Y/N)'(查找)
mov ah,9
int 21h ;顯示是否查找電話號碼
mov ah,1
int 21h ;由鍵盤輸入‘Y’或‘N’
cmp al,'y'
je loop0
cmp al,'Y'
jne exit ;不為‘Y'或'y'跳出轉至exit
jmp loop0;為‘Y'回車、換行
loop0: call crlf
lea dx,msg_sname ;'name?'
mov ah,9
int 21h ;顯示要查詢電話的姓名
call input_name ;輸入姓名
call name_search ;調用name_search
jmp rotate ;返回查找另一個電話
insert: call crlf
call stor_name
call input_phone
;call printline
;cmp namcount,1
;jb return1 ;表中項數小于1則要求輸入
call name_sort ;不小于調用name_sort
call printline
jmp rotate
exit1: lea dx,msg_illch ;輸入順序數不合法,重新輸入
mov ah,9
int 21h
jmp again
return:lea dx,msg_illcount ;輸入順序數超出號碼本容量,重新輸入
mov ah,9
int 21h
jmp again
return1:lea dx,msg_inputerr ;輸入錯誤,重新輸入姓名
mov ah,9
int 21h ;沒有輸入名字
jmp repeat0 ;出錯跳轉
exit: call printline ;輸出排序結果
mov ah,7
int 21h
jmp main
main endp ;主程序結束
;---------------------------------------------------------------------------------------------------------------------
name_search proc near ;(子程序)在表中順序查找輸入的名字
lea di,tel_tab ;把輸入的名字首地址放入di
push di ;保存名字表首址,di為指向tel_tab表項的指針
mov bx,namcount ;名字的個數放bx
loop1: lea si,namefld ;名字的緩存區首地址放入si
mov cx,20
repe cmpsb ;連續查找匹配名字
je found ;找到跳轉found
pop di ;沒找到di出棧
add di,28 ;把查找轉到下一個名字
push di
dec bx
jnz loop1 ;循環查找
lea dx,msg_nomatch
mov ah,9
int 21h ;一直沒找到則顯示沒有找到名字
mov ah,1
int 21h ;由鍵盤輸入‘Y’或‘N’
cmp al,'y'
je insert
;cmp al,'Y' ;此時di應指向插入位置
jne loop0 ;不為‘Y'或'y'跳轉至重新輸入名字查找
;jmp insert
found: pop di
lea dx,msg_outtitle
mov ah,9
int 21h
mov si,di ;把要找到的內容暫存在namtemp中
lea di,namtemp
mov cx,28
rep movsb
lea dx,namtemp
mov ah,9
int 21h ;顯示查到的姓名和電話號碼
ret
name_search endp
;-------------------------------------------------------------------------------------------------------
decibin proc near ;十進制轉化為2進制 ,并保存到bx中
mov bx,0 ;bx清零
mov dx,2 ;輸入數的位數置2
newchar:
mov ah,1
int 21h ;一號功能調用(輸入字符并回顯)
sub al,30h
jb exit2 ;非數字退出
cmp al,9
ja exit2 ;大于9退出(十進位制數每位0-9)
cbw ;字節轉換成字(al->ax)
xchg ax,bx ;交換ax、bx
mov cx,10
push dx
mul cx ;先保存,dx×10
xchg ax,bx ;再將ax、bx交換回
add bx,ax
pop dx
dec dx
jnz newchar ;位數不為0跳轉
exit2: ret
decibin endp ;結束
;---------------------------------------------------------------------------------------------------------
input_name proc near ;子程序(輸入名字)
lea dx,nameitem
mov ah,0ah
int 21h ;輸入名字并送入緩存區
call crlf ;回車、換行
mov bh,0
mov bl,ncurlen ;把名字的字符個數放入bx低位
mov cx,21 ;置循環次數
sub cx,bx
repeat1:mov namefld[bx],20h
inc bx
loop repeat1 ;輸入的名字為20字節,不足的用空格補足
ret
input_name endp
stor_name proc near ;子程序(傳送名字的每個字母到si)
inc namcount
cld ;df=0(從小到大)
lea si,namefld
mov cx,20
rep movsb ;重復傳送串名字(以字節為單位),直至送滿20即cx=0 ,di指向tel_tab
ret
stor_name endp
;---------------------------------------------------------------------------------------------------------------
input_phone proc near ;子程序(輸入電話號碼)
lea dx,msg_inputnum
mov ah,9
int 21h ;顯示要求輸入電話號碼
lea dx,phoneitem
mov ah,10
int 21h ;輸入電話號碼并送入緩存區
mov bh,0
mov bl,pcurlen
mov cx,9 ;置循環次數
sub cx,bx
repeat2:mov phonefld[bx],20h
inc bx
loop repeat2 ;輸入的電話為8字節,不足的用空格補足
call crlf
cld ;df=0
lea si,phonefld
mov cx,8
rep movsb ;把輸入的號碼存入namtab表中,重復傳送串電話號碼(以字節為單位)
ret
input_phone endp
;-------------------------------------------------------------------------------------------------------------------
name_sort proc near ;子程序(進行排序)
push di
push ax
push bx
cmp namcount,1
jz exit4 ;比較名字個數(只有一個名字即退出)
s1: mov swap,0
sub di,56;di指針后移兩個表項,第一次指向倒數第二項,以后每跑一趟前移一項
mov addend,di ;重新計算表尾指針
lea si,tel_tab
s2: mov cx,20 ;置循環計數值
mov di,si
add di,28 ;di->后項,si->前項
mov ax,di ;后項保存在ax
mov bx,si ;前項保存在bx
repe cmpsb ;源-目標,即前項如果大于后項,交換;
jbe s3
call exchange
s3: mov si,ax
cmp si,addend
jbe s2 ;是否已到namtab表尾,如果沒到繼續循環
cmp swap,0 ;如果有交換,繼續下一趟
jnz s1
exit4: pop bx
pop ax
pop di
ret
name_sort endp
;---------------------------------------------------------------------------------------------------
exchange proc near ;交換tel_tab中di,si所指表項的內容,前項保存在bx
mov cx,28
lea di,namtemp
mov si,bx
rep movsb
mov cx,28
mov di,bx
rep movsb
mov cx,28
lea si,namtemp
rep movsb
mov swap,1
ret
exchange endp
;------------------------------------------------------------------------------------------------
printline proc near ;輸出排序結果,不需要設置di,會改變di值
push di
push namcount ;保存namcount的值
call crlf
lea dx,msg_result ;'The result of sort is as follows:'
mov ah,9
int 21h ;顯示升序輸出姓名、電話
lea si,tel_tab
loop2: lea di,namtemp
mov cx,28 ;si每一次loop2會自動修正
rep movsb ;循環傳送姓名、電話至輸滿27字節即cx=0
lea dx,namtemp
mov ah,9
int 21h ;顯示姓名、電話
dec namcount ;名字數減1
jnz loop2 ;沒輸完則循環輸出
pop namcount
pop di
ret
printline endp
;----------------------------------------------------------------------------------------------------
deciasc proc near ;把10進制數轉換成相應的ASCII碼,digit in bl
mov ch,10d
mov cl,10d
re: ;判斷退出條件
cmp ch,0
je quit
mov al,bl;
cbw
div ch;
mov bl,ah
call printit
;a1a2a3... 遞推:x=an-1*10+an
;mov dl,al;商暫存在bl中
;mov dh,ah;余數暫存在dh中
;mov bh,0d;
;mov ax,bx
;mul cl
;mov bl,al
;add bl,dl
;除數ch=ch/10
mov al,ch
cbw
div cl
mov ch,al
;dec dh
jmp re
quit:
ret
deciasc endp
;------------------------------------------------------------------------------------------------
printit proc near ;輸出1位數字對應的ASCII碼,binary number in al
add al,30h
mov dl,al
mov ah,2
int 21h
ret
printit endp
;---------------------------------------------------------------------------------------------------
crlf proc near
mov dl,0dh
mov ah,2
int 21h
mov dl,0ah
mov ah,2
int 21h
ret
crlf endp
CODES ENDS
END START
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -