要求:
(1)创建一个电话号码表文件,每项包括人名(20个字符)及电话号码(8个字符)两部分。
(2)程序可接收输入人名及相应的电话号码,实现有序插入、查询、删除等操作。
编译环境:MASM6.15(教材32位汇编语言程序设计-钱晓捷)
请根据自己的环境适当修改代码。
;创建一个电话号码表文件;
;每项包括人名(20个字符)及电话号码(8个字符)两部分;
;程序可接收输入人名及相应的电话号码;
;实现有序插入、查询、删除等操作。
;ebx:全局存储电话簿的记录数
include io32.inc
telephone struct
name1 byte 20 dup(?)
phone byte 9 dup(?)
telephone ends
;电话簿的结构体
.data
select byte "please enter a option[1-6]&[5:menu]: ",0;功能选项
nbuffer byte 100 dup(?);姓名的缓冲区
tbuffer byte 100 dup(?);电话的缓冲区
people telephone 10 dup(<>);电话簿的容量
;菜单表
menu byte 13,10,"**********menu**********",
13,10,"input telephone--------1",
13,10,"search telephone-------2",
13,10,"delete telephone-------3",
13,10,"display telephone------4",
13,10,"display menu-----------5",
13,10,"exit-------------------6",
13,10,"**********end***********",13,10,0
.code
start:
xor ebx,ebx
xor ecx,ecx
;显示菜单
mov eax,offset menu
call dispmsg
.while eax!=0
again: mov eax,offset select
call dispmsg
xor eax,eax
call readsid
.if eax==1;输入数据
call input
.elseif eax==2;查询数据
call search
.elseif eax==3;删除数据
call delete
.elseif eax==4;显示数据
call display
.elseif eax==5;显示菜单
mov eax,offset menu
call dispmsg
.elseif eax==6;退出
mov eax,0
.else
jmp again
.endif
.endw
exit 0
;定义输入子程序
;有序输入,按姓名
input proc
lab0: pushad
;提示输入数据
mov eax,offset msg1;姓名
call dispmsg
lea eax,nbuffer
call readmsg;输入姓名
mov eax,offset msg2;电话
call dispmsg
lea eax,tbuffer
call readmsg;输入电话
;************存储数据**********
mov ebp,ebx;临时存储总记录
;无记录直接存储在第一个位置
.if ebx==0
;存姓名
mov ecx,20
lea edx,nbuffer
lea edi,(telephone ptr people[ebx]).name1
name1:mov al,[edx]
mov [edi],al
inc edx
inc edi
loop name1
;存电话
mov ecx,9
lea edx,tbuffer
lea edi,(telephone ptr people[ebx]).phone
phone:mov al,[edx]
mov [edi],al
inc edx
inc edi
loop phone
;输入成功
mov eax,offset msg4
call dispmsg
mov ecx,9999;成功的标志
jmp lab10;是否继续输入
;有记录,需判断存放位置
.else
mov ebx,0;从第一个记录开始
mov edx,ebp;总记录数
imul edx,29;记录存储的下一个偏移地址
;eg:0,1,2,3--4条记录,edx为第5的偏移地址
;控制循环,遍历电话簿,查找插入位置
.while ebx!=edx
mov ecx,20
lea esi,nbuffer
lea edi,(telephone ptr people[ebx]).name1
;比较姓名
lab1: mov al,[edi]
cmp [esi],al
jnz lab00;比较大小
inc edi
inc esi
loop lab1
;输入重复姓名
lea eax,msg3
call dispmsg
jmp lab10;是否继续输入
lab00: cmp [esi],al
jb lab2;输入姓名比记录数据小
cmp [esi],al
ja lab7;输入姓名比记录数据大,取下一条记录继续比较
lab2: mov edx,ebx;记录插入位置,即正在比较的数据
mov ebx,ebp;总记录数
imul ebx,29;最后位置的偏移地址
;移动数据,往后移动一格
.while ebx!=edx;edx当前比较得出的数据的偏移地址
lea edi,(telephone ptr people[ebx]).name1
sub ebx,29
lea esi,(telephone ptr people[ebx]).name1
mov ecx,20
;移动姓名
lab3: mov al,[esi]
mov [edi],al
inc esi
inc edi
loop lab3
.endw
;吧输入的数据插入至找到的位置ebx
;放入姓名
lea esi,nbuffer
lea edi,(telephone ptr people[ebx]).name1
mov ecx,20
lab4:mov al,[esi]
mov [edi],al
inc esi
inc edi
loop lab4
;移动数据,往后移动一格
mov ebx,ebp;总记录数
imul ebx,29;最后位置的偏移地址
;移动数据,往后移动一格
.while ebx!=edx;edx当前比较得出的数据的偏移地址
lea edi,(telephone ptr people[ebx]).phone
sub ebx,29
lea esi,(telephone ptr people[ebx]).phone
mov ecx,9
;移动电话
lab5: mov al,[esi]
mov [edi],al
inc esi
inc edi
loop lab5
.endw
;吧输入的数据插入至找到的位置ebx
;放入姓名
lea esi,tbuffer
lea edi,(telephone ptr people[ebx]).phone
mov ecx,9
lab6:mov al,[esi]
mov [edi],al
inc esi
inc edi
loop lab6
mov eax,offset msg4
call dispmsg
mov ecx,9999;插入成功标志
jmp lab10;是否继续输入
lab7: add ebx,29;取下一条记录继续比较,寻找位置
.endw;结束寻找位置
;插入的位置为末尾
mov ecx,20
lea edx,nbuffer
lea edi,(telephone ptr people[ebx]).name1
;存姓名
name0:mov al,[edx]
mov [edi],al
inc edx
inc edi
loop name0
;存电话
mov ecx,9
lea edx,tbuffer
lea edi,(telephone ptr people[ebx]).phone
phone0:mov al,[edx]
mov [edi],al
inc edx
inc edi
loop phone0
mov eax,offset msg4
call dispmsg
mov ecx,9999;插入成功标志
jmp lab10 ;是否继续输入
.endif
lab10:lea eax,again0;提示是否继续输入
call dispmsg
call readc
call dispcrlf
.if al==121;"y"
.if ecx==9999;之前插入成功
popad
inc ebx;ebx加一,总记录增加1
jmp lab0;继续寻找新位置插入
.else;插入失败
popad
jmp lab0;继续寻找新位置插入
.endif
.elseif al==110;"n";退出输入
.if ecx==9999;之前插入成功
popad
inc ebx;ebx加一,总记录增加1
jmp lab11;返回主程序
.else;插入失败
popad
jmp lab11;返回主程序
.endif
.else
jmp lab10;输入有误,重新输入
.endif
lab11:ret
msg1 byte "please input name:",0
msg2 byte "please input phoneNumber:",0
msg3 byte "Cannot input repeatedly!",13,10,0
msg4 byte "Input successfully!",13,10,0
again0 byte "Do you want to input again?[y/n]: ",0
input endp
;显示电话簿
;ebx:电话簿记录数
display proc
pushad
mov ecx,ebx;记录数,控制循环
;判断是否有记录
.if ecx!=0
mov esi,0;清零
;提示输入
mov eax,offset msgN
call dispmsg
mov ebx,1;序号
lable: mov eax,ebx;显示序号
call dispsid
mov al,46;句号
call dispc
;显示姓名
lea eax,(telephone ptr people[esi]).name1
call dispmsg
lea eax,msgS;显示间隔
call dispmsg
;显示电话
lea eax,(telephone ptr people[esi]).phone
call dispmsg
call dispcrlf
add esi,29;取下一条记录
inc ebx;序号加一
loop lable
.else;无记录
lea eax,msgE
call dispmsg
.endif
popad
ret
msgN byte "NAME TELEPHONE",13,10,0
msgS byte " ************* ",0
msgE byte "there are null!",13,10,0
display endp
;查询电话簿
;[1]按姓名查询[2]按手机号查询
search proc
pushad
mov ebp,ebx;临时存储电话簿中的记录数即ebx的值
lable1:mov ebx,ebp
xor edx,edx
xor esi,esi
xor edi,edi
;提示输入选择
lea eax,select0
call dispmsg
call readsib
call dispcrlf
;按姓名查询
.if al==1
lea eax,inputname;提示
call dispmsg
mov eax,offset nbuffer;输入姓名存放的地址即缓冲区
call readmsg
lea edi,nbuffer;取姓名地址
.while ebx!=0;依次遍历电话簿中的数据
lable2: lea edx,(telephone ptr people[esi]).name1;逐个取电话簿中的数据
mov ecx,20
;将输入的姓名和从电话簿中取得的姓名做比较
lable3: mov al,[edx]
cmp [edi],al
jnz lable4;不相等,取电话簿下一条数据
inc edx
inc edi
loop lable3;比较姓名
;找到记录,输出
mov eax,offset namemsg
call dispmsg
lea eax,(telephone ptr people[esi]).name1
call dispmsg
call dispcrlf
mov eax,offset telemsg
call dispmsg
lea eax,(telephone ptr people[esi]).phone
call dispmsg
call dispcrlf
mov ecx,9999;是否找到记录的标志
jmp lable5;退出,是否继续查询
lable4: add esi,29;取电话簿下一条记录
dec ebx;记录减一
.endw;结束遍历
;按电话查询
.elseif al==2
;提示输入选择
lea eax,inputtele
call dispmsg
mov eax,offset tbuffer;输入电话存放的地址即缓冲区
call readmsg
lea edi,tbuffer;取电话地址
.while ebx!=0;依次遍历电话簿中的数据
lea edx,(telephone ptr people[esi]).phone;逐个取电话簿中的电话
mov ecx,9
;将输入的电话和从电话簿中取得的电话名做比较
lable7: mov al,[edx]
cmp [edi],al
jnz lable8;;不相等,取电话簿下一条数据
inc edx
inc edi
loop lable7;比较电话
;找到记录,输出
mov eax,offset namemsg
call dispmsg
lea eax,(telephone ptr people[esi]).name1
call dispmsg
call dispcrlf
mov eax,offset telemsg
call dispmsg
lea eax,(telephone ptr people[esi]).phone
call dispmsg
call dispcrlf
mov ecx,9999;是否找到记录的标志
jmp lable5;退出,是否继续查询
lable8: add esi,29;取电话簿下一条记录
dec ebx;记录减一
.endw;结束遍历
.else
;输入有误,重新输入
jmp lable1
.endif
;判断是否查到记录
.if ecx!=9999
mov eax,offset nofind;未查询到记录
call dispmsg
call dispcrlf
.endif
lable5: lea eax,againmsg
call dispmsg
call readc
call dispcrlf
;是否继续查询
.if al==121;"y"
jmp lable1;;
.elseif al==110;"n"
jmp lable6
.else
jmp lable5
.endif
lable6:popad
ret
select0 byte " the way of search",13,10,"[1]:name [2]telephone: ",0
inputname byte "input name: ",0
inputtele byte "input telephone: ",0
namemsg byte "name: ",0
telemsg byte "telephone: ",0
againmsg byte "Do you want to search again?[y/n]: ",0
nofind byte "no search record!",13,10,0
search endp
;删除记录
;参数;输入待删除记录的姓名
;ebx:电话簿的记录数
delete proc
pushad
;mov esp,ebx;保护ebx数据,用于删除最后一条记录
xor esi,esi
;显示提示
lea eax,deletemsg
call dispmsg
lea eax,nbuffer;待删除记录姓名存放地址
call readmsg
;寻找待删除记录的位置
.while ebx!=0
mov edi,offset nbuffer
lea edx,(telephone ptr people[esi]).name1
mov ecx,20
lable20: mov al,[edx]
cmp [edi],al
jnz lable25;
inc edx
inc edi
loop lable20;比较姓名
;若待删除记录是最后一条数据
.if ebx==1;删除最后一个数据
lea edx,(telephone ptr people[esi]).name1
mov ecx,20
lable21:mov al,0
mov [edx],al
inc edx
loop lable21;删除姓名
lea edx,(telephone ptr people[esi]).phone
mov ecx,9
lable22:mov al,0
mov [edx],al
inc edx
loop lable22
mov ecx,9999;删除成功的标志
jmp lable26;删除电话
;删除其他位置的数据
.else
mov ebp,ebx;临时存储ebx,待删除数据的位置
dec ebx;需要移动记录次数,位置减一
;移动姓名
.while ebx!=0
mov ecx,20
lea edx,(telephone ptr people[esi]).name1
add esi,29
lea edi,(telephone ptr people[esi]).name1
lable23:mov al,[edi]
mov [edx],al
inc edi
inc edx
loop lable23
dec ebx
.endw
;移动电话
mov ebx,ebp;临时存储ebx,待删除数据的位置
dec ebx;需要移动次数
imul ebx,29;待删除数据位置的偏移地址
sub esi,ebx;esi重新定位待删除位置
mov ebx,ebp;
dec ebx;需要移动次数
.while ebx!=0
mov ecx,9
lea edx,(telephone ptr people[esi]).phone
add esi,29
lea edi,(telephone ptr people[esi]).phone
lable24:mov al,[edi]
mov [edx],al
inc edi
inc edx
loop lable24;删除姓名
dec ebx
.endw
mov ecx,9999;删除成功的标志
jmp lable26;删除电话
.endif
lable25:add esi,29;查询取下一条记录
dec ebx;记录减一
.endw;查找结束
lable26:.if ecx!=9999;删除失败
lea eax,Dfailed
call dispmsg
popad
.else;删除成功
lea eax,Dsuccess
call dispmsg
popad
dec ebx;记录减一
.endif
ret
deletemsg byte "input delete name: ",0
Dsuccess byte "Deleted successfully!",13,10,0
Dfailed byte "Delete failed!",13,10,"Please input correctly!",13,10,0
delete endp
end start
运行结果:
由于是刚开始学习汇编,代码编写有所不足,有很多冗余,欢迎有小伙伴能够指出不足之处,互相学习。