汇编原理实验 --电话簿的实现
實驗4:(電話本)
要求:
可放50項的電話號碼表,每項中有姓名(20)和電話號碼(8),存放聯系人,并且進行排序。并完成添加電話,根據姓名查詢電話,顯示輸出等功能
算法設計:
①數據結構:可放50項的電話號碼表,每項中有姓名(20)和電話號碼(8)。數據定義則用tel_tab ?db 50 dup(20 dup(' '),8 dup(' ')),即可滿足,每項用空白符初始化
②.1存放輸入的數據:tel_name和tel_num分別存放用戶輸入的姓名和電話號碼。di初始化為電話簿tel_tab的首地址,使用movsb完成字符串的賦值,因此,di指向傳送的目標地址,si為源地址,cx賦值為傳送的字節數,轉送名字時,cx=20,傳送電話時,cx=8。循環輸入電話簿項中di會跟著movsb而變化,代表接下來用戶傳送的目標位置,而si每次需重置為緩存區的首地址。這樣就完成了用戶輸入的名字電話存到tel_tab中。在此基礎上,完成排序等功能。
②.2.用戶輸入緩沖區中的數據需要將剩下的空間用空格代替,具體原因會在討論與結論中說明。主要原因是,用戶輸入的字符串一般為回車符結尾,倘若連回車符也一起賦到了tel_tab中,則在輸出tel_tab中會完成了輸出電話簿信息的效果。所以每次輸入姓名和電話時,要把緩存區剩余空間(包括回車符)一起用空白符填滿,空白符填入的個數=總長度-輸入字符的長度
③、排序:每次名字轉入電話簿后都要對電話簿進行重新排序(字典序)。采用排序的最佳方法是插入排序,因為每次插入數據時,tel_tab中的數據都已經排好了,只要找到比用戶輸入名字大的電話簿項時,將次內存后的所有數據都向后移28個字節,然后再把名字和電話存入該位置。
④、輸出:起始地址tel_tab,每輸出28個字符換行回車。
程序實現:(代碼見附錄)
?
①、輸入名字和電話,剩余用空白符代替:調用inputname和inputtel子程序即可。
②、將tel_name和tel_num存入tel_tab中,調用stor_name和stor_mun,子程序。主要采用movsb命令符
③、指定字符串后移28個字節: moveto28byte子程序,因為電話簿每一項長度為28個字節,所以cx賦值28,然后si字符串首地址,di=si+28,使用movsb傳送
④、插入排序:需要一個變量tel_count來存放電話簿項個數,當插入數據時比較到比自己大時,從電話簿最后一項開始,每一項調用moveto28byte子程序,然后再將數據放到電話簿中
⑤、輸出電話簿:cx=28*tel_count。
⑥、查詢名字并輸出:用sea_name緩沖區存放要查詢的名字(記得用空白符將剩下空間填滿)。匹配兩字符串是否相等,教課書上有代碼就不再多說,把名字都遍歷一遍,如果匹配成功,另匹配到的名字首地址加上20個字節,即為對應的電話號碼首地址,將其輸出即可。
DATAS SEGMENT;此處輸入數據段代碼 tel_name db 20namelen db 0namefld db 20 dup(?)tel_num db 8numlen db 0numfld db 8 dup(?)tel_tab db 50 dup(20 dup(' '),8 dup(' '))tel_count db 0pushunit db 0turnnewline db 28string1 db 'Input name:$'string2 db 'Input a telephone number:$'string3 db 'Please add telephone into table(n/y)$'string4 db 'search telephone by name:$ 'string5 db 'noresult$'strSeaName db 20 ;根據名字查詢電話seanamelen db 0seanamefld db 20 dup(?)outputname db 0 ;查詢電話時記錄匹配不成功的次數 DATAS ENDSSTACKS SEGMENT;此處輸入堆棧段代碼 STACKS ENDSCODES SEGMENTASSUME CS:CODES,DS:DATAS,SS:STACKS START:MOV AX,DATASMOV DS,AXmov es,axcldlea di,tel_tab; 輸出Inputname addphone:mov dx,offset string3call print mov ah,01hint 21hcall printnewline;cmp al,59h;jne searchphonecmp al,79hjne printtable ;如果鍵入不是y或Y則進入查詢號碼mov dx,offset string1call print call Inputnamecall stor_name ;把名字存放在tel_tab中mov dx,offset string2call printcall inputtelcall stor_num ;把電話存放在tel_tab中call name_sort ;排序jmp addphone printtable: ;打印電話簿lea bx,tel_tab;lea dx,tel_tab;call moveto28bytemov al,tel_countmov ah,28mul ahmov cx,ax printtableline:mov dl,[bx]mov ah,02hint 21hinc bxdec turnnewlinemov al,turnnewline cmp al,0jne nochange1mov turnnewline,28call printnewline nochange1: loop printtableline namesearch: ;查詢電話mov dx,offset string4call print lea dx,strSeaNamecall cincall printnewlinemov bl, seanamelenmov cx, 20sub cx, bx namebrk1: ;將人名除外所剩下的字符用空格填滿mov seanamefld[bx], 20hinc bxloop namebrk1 ;比較字符串大小mov cl,tel_count lastp: push cxmov si,offset seanamefldmov di,offset tel_tab ;+outputname*28mov al,outputnamemov bl,28mul bladd di,axmov cx,20cld lastagain: cmpsbjnz lastunmatloop lastagain;匹配成功mov al,0jmp lastoutput lastunmat: mov al,-1 pop cxinc outputnameloop lastp lastoutput: cmp al,0jne noresultmov cx,8 matchname:mov dl,[di]mov ah,02hint 21hinc diloop matchnamejmp stop noresult:mov dx,offset string5call print stop:MOV AH,4CHINT 21H;其他子程序 name_sort proc ;對名字和電話一起排序 ,待完成 push dx push bx push cx push axmov dx,di push disub dx,28 ;剛剛輸入的姓名的地址lea bx,tel_tab mov cl,tel_countsortagain:cmp bx,dxje sortendcall strcompareadd bx,28cmp al,1 ;如果剛剛輸入的姓名大,那就繼續循環jne index1loop sortagain index1:mov al,tel_count ;ax=(tel_count-cx)*28為要放的單元數 ;如果小的話,把當前之后的名字后移28個字節,再把名字插入到當前位置sub al,clmov ah,28MUL ah allmove:call moveto28bytesub dx,28loop allmovejmp putintoputinto:mov si,di ;剛剛輸入名字的新地址lea di,tel_tabadd di,axmov cx,28rep MOVSB sortend: pop di pop ax pop cx pop bx pop dxret name_sort endpmoveto28byte proc ;dx為當前地址28位各后移28個字節push cxpush bx push sipush di mov bx,dxadd bx,28mov si,dxmov di,bxmov cx,28rep MOVSBpop dipop sipop bxpop cx ret moveto28byte endpInputname proc ;輸入名字lea dx,tel_namecall cinmov bl, namelenmov cx, 20sub cx, bx namebrk: ;將人名除外所剩下的字符用空格填滿mov namefld[bx], 20hinc bxloop namebrk ret Inputname endpstor_name procinc tel_countcldmov si,offset tel_name+2;mov di,offset tel_tabmov cl,20rep MOVSBret stor_name endpInputtel proclea dx,tel_numcall cinmov bl, numlenmov cx, 8sub cx, bx numbrk: ;將人名除外所剩下的字符用空格填滿mov numfld[bx], 20hinc bxloop numbrk ret Inputtel endpstor_num proccldlea si,numfld;mov di,offset tel_tabmov cl,8rep MOVSBret stor_num endp;打印固定字符串,入口參數dx指向的地址以$符號結束 print procpush axmov ah,09hint 21hpop axret print endp ;用戶輸入,入口參數dx指向第一個緩沖區地址 cin procpush axmov ah,0AHint 21hpop axcall printnewlineret cin endp ;輸出換行 printnewline procpush axpush dxmov ah,02hmov dl,0dhint 21hmov dl,0ahint 21hpop dxpop axret printnewline endp ;字符串大小比較(字典序) strcompare proc ;入口參數dx,bx的首地址,dx大于bx則輸出al為1,否則為0 push si push di push cxmov si,dxmov di,bx push bx push dxmov cx,20cld stragain:mov bl,[si]cmp bl,[di]jb unmat1cmp bl,[di]ja unmat2inc siinc diloop stragain unmat1: mov al,0jmp endstrcompare unmat2: mov al,1 endstrcompare: pop dx pop bx pop cx pop di pop siret strcompare endp CODES ENDSEND START輸出結果如圖:
總結
以上是生活随笔為你收集整理的汇编原理实验 --电话簿的实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 汇编原理实验 --类型统计(字母,数字,
- 下一篇: 汇编原理实验 --计算平均数