[汇编语言]实现电话簿的创建

要求:
(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       
                  

运行结果:
运行结果

由于是刚开始学习汇编,代码编写有所不足,有很多冗余,欢迎有小伙伴能够指出不足之处,互相学习。

指路->其他实验.

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值