实在不好意思,请各位帮忙做一个汇编的实验题(急) -- By 萧月禾(300分)

  • 主题发起人 萧月禾
  • 开始时间

萧月禾

Unregistered / Unconfirmed
GUEST, unregistred user!
是帮一个在校生(非计算机专业)做的,他搞不定,老师又催得急
所以只好找我帮忙

不是我要偷懒,而我的汇编实在忘得干干净净了
最近自己的工作又忙
所以只好厚着脸皮上来请大家帮忙了

而且非常急,还忘尽快
我知道大家对直接找人帮忙写程序一向看不惯
可我没办法,得罪之处,还望原谅!

程序中最好有多些注释
另外,在校的朋友如果手头上有现成的可提供,在下不胜感激

原题:

实验2.4 查找电话号码
1. 题目:查找电话号码phone
2. 实验要求:
(1) 要求程序建立一个可存放50项的电话号码表,每项包括人名(20个字符)及电话号码(8个字符)两部分;
(2) 程序可接收输入人名及相应的电话号码,并把它们加入电话号码表中;
(3) 凡有新的输入人名后,程序应按人名对电话号码表重新排序;
(4) 程序可接收需要找电话号码的人名,并从电话号码表中查出其电话号码,再在屏幕上以如下格式显示出来。
Name tel.
X X X X X X X X

3. 提示:程序采用子程序结构。主程序的主要部分如下:
A. 显示提示符 ‘Input name:’;
B. 调用子程序input_name 接收人名;
C. 调用子程序stor_name 把人名存入电话号码表tel_tab 中;
D. 显示提示符’Input a telephone number:’;
E. 调用子程序inphone 接收电话号码,并把它存入电话号码表 tel_tab 中
F. 如输入已结束则调用 name_stor 子程序对电话号码表按人名排序;
G. 显示提示符 ‘Do you want a telephone number ?(Y/N)’;
H. 回答N则退出程序;
I. 回答Y则再显示提示符’ name ?‘;
J. 调用 input_name 子程序接收人名;
K. 调用 name_search 子程序在电话号码表中查找所要的电话号码;
L. 调用 printline 子程序按要求格式显示人名及电话号码;
M. 重复查号提示符直至用户不再要求查号为止。

4. 实验报告要求:
除以上要求外,还应增加以下内容:
A 画出模块层次图;
B 写出各模块说明。
 
我有一个办法,用C或者Pascal写这样一个console程序,然后将其反汇编。。。。
 
哇塞,短点的都不一定能搞出来了
这么长,我也忘差不多了,没时间重新翻书了:)
 
朋友,你这个题目太大啦。
我是懂一点点汇编,如果你只问一个技术问题我还可以帮你搞一下,可你一下来就
搞这么多,我都晕啦。
工作忙啊,再说还是孤身一人,有时间还想去泡妹妹呢!
不好意思!
 
没法我不会汇编,给哥哥帮忙顶
 
好象是要DOS下的汇缟
 
我的汇编忘光了,我今晚回去找找,看我本科时的汇编实验程序还在不在,不过我想
多半是找不到了。
 
今天没时间,明天有时间的话再说,好了
 
太长了。。
用16位的吧~
以前写过哦。。

还是让他自己来,学生多的是时间,干嘛去?又是去泡MM了~~




 
我本科做实验时写的汇编程序,现在自己也看不懂了。至于模块层次图就没有了:
--------------------------------------------
title zw3_phone
data_seg segment
inname db 21,?,21 dup(' ')
tel_tab db 50 dup (28 dup(?))
number db 9,?,9 dup(?)
count db 0
sum dw 0
count1 dw 0
temp db 28 dup(?),'$'
mess1 db 'input name(enter for none):','$'
mess2 db 'input a telephone number:','$'
mess3 db 'do you want a telephone number?(y/n)','$'
over db 'game over,thankyou!','$'
namea db 'name?(enter for none)','$'
sorry db 'sorry,not found.','$'
cr db 10,13,'$'
namex dw 0
tabx dw 0
searchx dw 0
data_seg ends
code_seg segment
;**************************main********************

assume cs:code_seg,ds:data_seg,es:data_seg
start: mov ax,data_seg
mov ds,ax
mov es,ax
write macro line
lea dx,line
mov ah,9
int 21h
endm
repeata: call input_name
call crlf
mov dh,inname+2
cmp dh,0dh
jz continue1
call stor_name
call inphone

call crlf
call name_sort

jmp repeata
continue1:
dec count
dec count1
mov al,count
mov dl,28
mul dl

mov sum,ax
call crlf
write mess3
mov ah,1
int 21h
cmp al,'y'
jne exita
call crlf
nextname: call crlf
write namea
call enter_name
mov dl,inname+2
cmp dl,0dh
jz exita
call crlf
mov searchx,0
call name_search
call crlf
jnz nextname
exita:call crlf
write over
mov ax,4c00h
int 21h
;*******************crlf***************************
crlf proc near
push dx
push ax
lea dx,cr
mov ah,9
int 21h
pop ax
pop dx
ret
crlf endp
;*******************input_name*********************
input_name proc near
lea dx,mess1
mov ah,9
int 21h
lea di,inname+2
mov al,20h
mov cx,20
rep stosb

lea dx,inname
mov ah,10
int 21h

inc count
inc count1


ret
input_name endp
;*******************stor_name***********************
stor_name proc near
mov cx,20
lea si,inname+2
mov bx,namex
lea di,tel_tab[bx]
cld
rep movsb
add namex,28
ret
stor_name endp
;**********************inphone************************
inphone proc near
lea dx,mess2
mov ah,9
int 21h
lea dx,number
mov ah,10
int 21h
mov cx,8
lea si,number+2
lea di,tel_tab[bx+20]
cld
rep movsb
call crlf
ret
inphone endp
;**********************name_sort**********************
name_sort proc near
mov cx,0
mov cl, count
dec cl
mov count1,cx

cmp count,1
je ex
repeat1: mov tabx,0
mov bx,0
repeat2: push cx
mov dl,tel_tab
mov bx,tabx
cmp dl,tel_tab[bx+28]
;int 3
jc next

mov cx,28
lea si, tel_tab[bx]
lea di, temp
cld
rep movsb

mov cx,28
lea si,tel_tab[bx+28]
lea di,tel_tab[bx]
cld

rep movsb

mov cx,28
lea si,temp
lea di,tel_tab[bx+28]
cld
rep movsb

next: add tabx,28
pop cx

loop repeat2
dec count1
mov dx,count1
cmp dx,0
mov cx,count1
jnz repeat1
ex: ret
name_sort endp
;*********************enter_name***************************
enter_name proc near

lea di,inname+2
mov al,20h
mov cx,20
rep stosb

mov ah,10
lea dx,inname
int 21h
ret
enter_name endp
;**********************name_search**************************
name_search proc near
repeatb:
mov cl,inname+1
inc cl
mov ch,0
mov bx,searchx
lea si,tel_tab[bx]
lea di,inname+2
cld
repz cmpsb
cmp cx,0
jz exitb
add searchx,28
mov dx,sum
cmp dx,searchx
jae repeatb
mov ah,9
lea dx, sorry
int 21h
jmp exit0
exitb: call printline
exit0: ret
name_search endp
;**********************printline********************************
printline proc near
mov cx,28
mov bx,searchx
repeatc: mov dl,tel_tab[bx-5]
mov ah,2
int 21h
inc bx
loop repeatc
ret
printline endp
code_seg ends
end start
 
写了 三个下午 + 三个晚上,总算搞定了:(竟然已经有人贴了,够快)
我可是现写的,调试太累了,800 多行代码:(
结构还算清晰,复杂的地方都有注释:

data segment
;
; consts
CR EQU 13
LF EQU 10
MaxRecCnt EQU 50
NameLen EQU 20
NumLen EQU 8
NameFieldLen EQU 1+1+NameLen
NumFieldLen EQU 1+1+NumLen
;
; string resources
strReturn db CR, LF, '$'
strInputName db 'Input a Name: $'
strInputNumber db 'Input a Telephone Number: $'
strDispName db 'Name:$'
intDispNameLen db $ - strDispName - 1
strDispNumber db 'Number:$'
strInsertAnother db 'Insert another record? (Y/N)$'
strWantNumber db 'Do you want a Telephone Number? (Y/N)$'
strNameNotFound db 'Do not have such a record.$'
;
; table of telephone notebook
Tele_Table db MaxRecCnt dup(NameLen,?,NameLen dup(0), NumLen,?,NumLen dup(0))
Tele_RecCount db 0
Tele_RecSize db NameFieldLen + NumFieldLen
;
; variables
NameBuffer db NameLen, ?, NameLen dup(0)
;
data ends

code segment
assume cs: code, ds: data

; procedure MinMax(Num1: cl; Num2: ch)
; move Min(Num1, Num2) to cl, and Max(Num1, Num2) to ch.
; (in): cx
; (out): cx
MinMax proc far
cmp cl, ch
jbe MinMax_Do_Not_Change
; else, cl > ch, do change
xchg cl, ch

MinMax_Do_Not_Change:
ret
MinMax endp

; procedure DispCRLF()
; display CRLF, to start a new line.
; (in): None
; (out): None
DispCRLF proc far
push ax
push dx

mov ah, 2
mov dl, CR
int 21h
mov dl, LF
int 21h

pop dx
pop ax
ret
DispCRLF endp

; procedure DispBlanks(Count: bx)
; display Count blanks.
; (in): bx
; (out): None
DispBlanks proc far
push dx
push bx
push ax

mov ah, 2
mov dl, ' '
Display_Blanks_Begin:
cmp bx, 0
jz Display_Blanks_Finish
int 21h
dec bx
jmp Display_Blanks_Begin
Display_Blanks_Finish:

pop ax
pop bx
pop dx
ret
DispBlanks endp

; procedure DispStr(Addr: dx)
; display the string, which address is spec. in Addr.
; (in): dx
; (out): None
DispStr proc far
push ax

mov ah, 9
int 21h

pop ax
ret
DispStr endp

; procedure DispStrCRLF(Addr: dx)
; display the string with CRLF, which address is spec. in Addr.
; (in): dx
; (out): None
DispStrCRLF proc far
push ax

mov ah, 9
int 21h
call DispCRLF

pop ax
ret
DispStrCRLF endp

; procedure InputChar(Buff: al)
; input a char.
; (in): None
; (out): al
InputChar proc far
push bx

mov bh, ah
mov ah, 1
int 21h
mov ah, bh

pop bx
ret
InputChar endp

; procedure InputStr(Addr: dx)
; input a string, [Addr] is the max size of buffer; [Addr + 1] is the actual
; size of the string; [Addr + 2] is the address of the inputed string.
; (in): dx
; (out): None
InputStr proc far
push ax

mov ah, 10
int 21h

pop ax
ret
InputStr endp

; procedure TerminateStr(Addr: dx)
; set the end of the string to '$' to STOP the display of this string.
; [Addr + 1] holds the actual size of the string; [Addr + 2] points to the
; beginning of the string.
; (in): dx
; (out): None
TerminateStr proc far
push dx
push bx

mov bx, dx
inc bx ; now, [bx] is the actual size of the string
mov bl, [bx] ; now, bl is the actual size of the string
xor bh, bh ; now, bx is the actual size of the string

add dx, 2 ; point to the beginning of the string
add dx, bx ; point to the end of the string
mov bx, dx
mov [bx], byte ptr '$' ; append a '$' to the end

pop bx
pop dx
ret
TerminateStr endp

; procedure CompareString(Src: si; Dst: di)
; compare 2 strings. [Src - 1] and [Dst - 1] hold the length of the string.
; Src < Dst: SF = 1, ZF = 0; Src > Dst: SF = 0, ZF = 0; Src = Dst: ZF = 1.
; (in): si, di
; (out): flags
CompareString proc far
push si
push di
push cx
push bx
push ax

mov cl, [si - 1] ; length of Src
mov ch, [di - 1] ; length of Dst
mov bx, cx

; if any string is nil
or cl, ch
jz Compare_Equal ; length of both strings are zero
cmp bl, 0
je Compare_Below ; length of Src is zero
cmp bh, 0
je Compare_Above ; length of Dst is zero
mov cx, bx ; restore cx

; make cx = Min(cl, ch), it will be the counter below
call MinMax ; now, cl = Min(ch, cl)
xor ch, ch ; now, cx = Min(ch, cl)

; start compare
Compare_Next_Char:
mov al, [si]
mov ah, [di]
cmp al, ah
jb Compare_Below
ja Compare_Above
inc si
inc di
dec cx
jnz Compare_Next_Char
; comes to here, only 2 conditions: SubStr or Equal
cmp bl, bh ; just check the length of them
jb Compare_Below
ja Compare_Above

Compare_Equal:
xor bx, bx ; now, ZF = 1

jmp Compare_Finish
Compare_Below:
add bx, 0 ; now, ZF = 0
stc ; set CF to 1
jmp Compare_Finish
Compare_Above:
add bx, 0 ; now, ZF = 0
clc ; set CF to 0

Compare_Finish:

pop ax
pop bx
pop cx
pop di
pop si
ret
CompareString endp

; procedure XChangeMemory(Src: si; Dst: di; Len: cx)
; swap 2 block of memory. size is spec. in cx.
; Src <-> Dst
; (in): si, di, cx
; (out): None
XChangeMemory proc far
push di
push si
push cx
push bx

XChange_Begin:
jcxz XChange_Finish
mov bl, [si]
mov bh, [di]
mov [si], bh
mov [di], bl
inc si
inc di
dec cx
jmp XChange_Begin

XChange_Finish:

pop bx
pop cx
pop si
pop di
ret
XChangeMemory endp

; procedure CalcRecOffset(RecNo: cx)
; calculate the offset of a spec. record.
; the result is add to dx
; (in): cx
; (out): dx
CalcRecOffset proc far
push cx

; loop to calculate the offset of a spec. record
Start_Calculate:
test cx, cx
jz Finish_Calculate
add dl, Tele_RecSize
adc dh, 0
dec cx
jmp Start_Calculate
Finish_Calculate:

pop cx
ret
CalcRecOffset endp

; procedure QueryInputName()
; display the query string before input name.
; (in): None
; (out): None
QueryInputName proc far
push dx

lea dx, strInputName
call DispStr

pop dx
ret
QueryInputName endp

; procedure InputName(Buffer: dx)
; input a name into Buffer.
; (in): dx
; (out): None
InputName proc far
call InputStr
call TerminateStr

ret
InputName endp

; procedure DisplayName(RecNo: cx)
; display the name in the record which record no. is spec. in RecNo.
; (in): cx
; (out): None
DisplayName proc far
push dx
push bx

lea dx, Tele_Table
call CalcRecOffset

; now, dx holds the address of the spec. record
add dx, 2 ; the string buffer is at offset + 2
call DispStr

; display some blanks to fit to the same width with other names
mov bx, dx
dec bx ; now, [bx] is the actual length of string
mov bl, [bx]
xor bh, bh ; clear bh
mov dx, bx ; dx is the actual length of string
mov bx, NameLen
sub bx, dx ; bx is the number of blanks to be displayed
call DispBlanks

pop bx
pop dx
ret
DisplayName endp

; procedure QueryInputNumber()
; display the query string before input name.
; (in): None
; (out): None
QueryInputNumber proc far
push dx

lea dx, strInputNumber
call DispStr

pop dx
ret
QueryInputNumber endp

; procedure InputNumber(Buffer: dx)
; input a telephone number into Buffer
; (in): dx
; (out): None
InputNumber proc far
push dx

add dx, NameFieldLen ; point to the address of Num. field
call InputStr
call TerminateStr

pop dx
ret
InputNumber endp

; procedure DisplayNumber(RecNo: cx)
; display the telephone num in the record which record no. is spec. in RecNo.
; (in): cx
; (out): None
DisplayNumber proc far
push dx

lea dx, Tele_Table
call CalcRecOffset

; now, dx holds the address of the spec. record
add dx, NameFieldLen ; point to the address of Num. field
add dx, 2 ; the string buffer is at offset + 2
call DispStr

pop dx
ret
DisplayNumber endp

; procedure AppendRecord()
; append a record behind the telephone notebook.
; (in): None
; (out): None
AppendRecord proc far
push dx
push cx

lea dx, Tele_Table
xor cx, cx
mov cl, Tele_RecCount
call CalcRecOffset
; now, dx holds the address of the new record to be inserted

call QueryInputName
call InputName
call DispCRLF

call QueryInputNumber
call InputNumber
call DispCRLF

inc Tele_RecCount

pop cx
pop dx
ret
AppendRecord endp

; procedure DisplayRecord(RecNo: cx)
; display a spec. record which record no. is spec. in RecNo.
; (in): cx
; (out): None
DisplayRecord proc far
call DisplayName
call DisplayNumber
call DispCRLF

ret
DisplayRecord endp

; procedure AppendRecords()
; append records in a loop
; (in): None
; (out): None
AppendRecords proc far
push dx
push ax

Continue_Append:
call DispCRLF
call AppendRecord

call DispCRLF
lea dx, strInsertAnother
call DispStr
call InputChar ; result is in al
cmp al, 'y'
jz Continue_Append
cmp al, 'Y'
jz Continue_Append

call DispCRLF

pop ax
pop dx
ret
AppendRecords endp

; procedure DisplayRecTitle()
; display the column title of records.
; (in): None
; (out): None
DisplayRecTitle proc far
push dx
push bx

; display the name title
lea dx, strDispName
call DispStr
xor bh, bh
mov bl, NameLen
sub bl, intDispNameLen
call DispBlanks

; display the number title
lea dx, strDispNumber
call DispStrCRLF

pop bx
pop dx
ret
DisplayRecTitle endp

; procedure DisplayRecords()
; display all the records in the telephone notebook.
; (in): None
; (out): None
DisplayRecords proc far
push dx
push cx
push bx

call DispCRLF
call DisplayRecTitle

; display contents
xor bx, bx
mov bl, Tele_RecCount
xor cx, cx
Display_Next_Record:
call DisplayRecord
inc cx
cmp bx, cx
jg Display_Next_Record

pop bx
pop cx
pop dx
ret
DisplayRecords endp

; procedure CompareRecName(RecA: bl; RecB: bh)
; compare 2 names, NameA and NameB is the record no.
; NameA < NameB: CF = 1, ZF = 0; NameA > NameB: CF = 0, ZF = 0;
; NameA = NameB: ZF = 1.
; (in): bx
; (out): flags
CompareRecName proc far
push si
push di
push dx
push cx

cmp bl, bh ; if RecA = RecB, do not compare
je Compare_Rec_Same

; si <- NameA
lea dx, Tele_Table
xor cx, cx
mov cl, bl
call CalcRecOffset
mov si, dx ; point to the record
inc si
inc si ; point to the Name buffer

; di <- NameB
lea dx, Tele_Table
xor cx, cx
mov cl, bh
call CalcRecOffset
mov di, dx ; point to the record
inc di
inc di ; point to the Name buffer

call CompareString
; flags have been set already
jmp Compare_Rec_Finish

Compare_Rec_Same:
xor cx, cx ; set ZF = 1

Compare_Rec_Finish:

pop cx
pop dx
pop di
pop si
ret
CompareRecName endp

; procedure XChangeRecord(RecA: bl; RecB: bh)
; swap 2 records, RecA and RecB is the record no.
; RecA <-> RecB
; (in): bx
; (out): None
XChangeRecord proc far
push si
push di
push dx
push cx

cmp bl, bh ; if RecA = RecB, do not change
je XChange_Rec_Finish

; si <- RecA
lea dx, Tele_Table
xor cx, cx
mov cl, bl
call CalcRecOffset
mov si, dx ; point to the record

; di <- RecB
lea dx, Tele_Table
xor cx, cx
mov cl, bh
call CalcRecOffset
mov di, dx ; point to the record

xor ch, ch
mov cl, Tele_RecSize
call XChangeMemory

XChange_Rec_Finish:

pop cx
pop dx
pop di
pop si
ret
XChangeRecord endp

; procedure SortRecordsByName()
; sort all the records by name
; (in): None
; (out): None
SortRecordsByName proc far
push dx
push cx
push bx
push ax

xor ch, ch
mov cl, Tele_RecCount
cmp cl, 1
jle Sort_Name_Finish; if record count <= 1, do not sort
dec cx ; record no. is starts from index 0

;for dl := 0 to cl - 1 do
;begin
; al := dl;
; for dh := dl + 1 to cl do
; begin
; bl := al;
; bh := dh;
; CompareRecName;
; if Rec(al) > Rec(dh) then
; al := dh;
; end;
; bl := dl;
; bh := al;
; XChangeRecord;
;end;

xor dx, dx
Sort_Name_Outer_Loop:
mov al, dl ; use al to store the Min name rec. no.

mov dh, dl
inc dh ; dh = dl + 1
Sort_Name_Inner_Loop:
mov bl, al
mov bh, dh
call CompareRecName ; Rec(Min) - Rec(dh)
jbe Sort_Name_Below_Or_Equal
; Rec(min) > Rec(dh), so dh is the new Min
mov al, dh ; move new Min to al
Sort_Name_Below_Or_Equal:
inc dh
cmp dh, cl
jbe Sort_Name_Inner_Loop

mov bl, dl
mov bh, al
call XChangeRecord ; exchange Rec(dl) and Rec(Min)
inc dl
cmp dl, cl
jb Sort_Name_Outer_Loop
Sort_Name_Finish:

pop ax
pop bx
pop cx
pop dx
ret
SortRecordsByName endp

; procedure FindRecordByName(Name: dx)
; find a certain record by Name. result record no. is in cl.
; if Name not found, cl is 0FFH. ch is NOT certain!
; (in): dx
; (out): cx
FindRecordByName proc far
push di
push si
push dx
push bx

xor cl, cl
mov ch, Tele_RecCount
cmp ch, 0 ; no record to be found
jz Find_Record_Name_Not_Found
xor bh, bh
mov bl, Tele_RecSize

mov si, dx ; point si to the name user input
lea di, Tele_Table ; point di to names in the notebook
add si, 2 ; point to the string buffer
add di, 2 ; point to the string buffer

Find_Next_Record_Name:
call CompareString
jz Find_Record_Name_Finish ; with flag set already
add di, bx ; point di to the string buffer of next record
inc cl
cmp ch, cl
ja Find_Next_Record_Name
; comes here, means not found

Find_Record_Name_Not_Found:
mov cl, 0FFH

Find_Record_Name_Finish:

pop bx
pop dx
pop si
pop di
ret
FindRecordByName endp

; procedure DispFindResult(RecNo: cl)
; display the result of find.
; (in): cl
; (out): None
DispFindResult proc far
push dx
push cx

cmp cl, 0FFH
jne Disp_Record_Name_Found

Disp_Record_Name_Not_Found:
call DispCRLF
lea dx, strNameNotFound
call DispStrCRLF
jmp Disp_Record_Result_Finish

Disp_Record_Name_Found:
call DispCRLF
xor ch, ch
call DisplayRecTitle
call DisplayRecord

Disp_Record_Result_Finish:

pop cx
pop dx
ret
DispFindResult endp

; procedure FindRecord()
; find a certain record which the name is spec. by user.
; (in): None
; (out): None
FindRecord proc far
push dx
push ax

Continue_Find_Record:
call DispCRLF
lea dx, strWantNumber
call DispStr
call InputChar ; result is in al
xor al, 'Y'
and al, 0DFH ; if input 'y' or 'Y', al will be 0
jnz Find_Record_Finish
; else, do find
call DispCRLF
call QueryInputName
lea dx, NameBuffer
call InputName
call FindRecordByName
call DispFindResult
jmp Continue_Find_Record
Find_Record_Finish:

pop ax
pop dx
ret
FindRecord endp

; procedure main
main proc far
start:
push ds
xor ax, ax
push ax

mov ax, data
mov ds, ax
mov es, ax

; main code starts here
call AppendRecords
call DisplayRecords
call SortRecordsByName
call DisplayRecords
call FindRecord

ret
main endp

code ends
end start

 
哎!好似甲骨文啊!
 
呵呵,多些二位的帮忙[:)]
 
顶部