彙編實驗----電話號碼

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


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章