王士伟吧 关注:169贴子:3,318

【汇编语言】电话号码查询程序

只看楼主收藏回复

http://vcbin.blogchina.com/3742015.html

【汇编语言】电话号码查询程序                                       

;实现电话号码插入和查询

data_seg segment
namcount dw 0                 ;存入名字的个数
tel_tab db 50 dup(28 dup(' '))         ;表格

nameitem label byte
nmax db 21
ncurlen db ?
namefld db 21 dup(?)         ;姓名缓冲区

phoneitem label byte
pmax db 9
pcurlen db ?
phonefld db 9 dup(?)         ;电话号码缓冲区

addend dw ?                 ;排序时的tel_tab尾地址指针
namtemp db 28 dup(?),13,10,'$'         ;临时保存表中一项
swap db 0                           ;排序中是否有交换的标志位

msg_count db 'Please enter the count you want to input?',13,10,'$'
msg_illcount db 'Error:The number of your enter exceed the limit of 50! Plesae input the number again!',13,10,'$'
msg_illch db 'Error:The number of your enter is illegal! Please intput the number again!',13,10,'$'
msg_inputnam db 'Input name:','$'
msg_inputerr db 'Error:Input error!,please input a name!',13,10,'$'
msg_inputnum db 'Input a telephone number:','$'
msg_inquire db 'Do you want a telephone number?(Y/N)','$'
msg_sname db 'name?',13,10,'$'
msg_outtitle db 'name                tel.',13,10,'$'
msg_nomatch db 'No such name!Do you want to insert this item(Y/N)?',13,10,'$'
msg_result db 'The Phone Dictionary is listed  as follows:',13,10,'$'
data_seg ends

stack_seg segment para stack 'stack'      ;定义堆栈段
dw 256 dup(0)
stack_seg ends

code_seg segment

assume cs:code_seg,ds:data_seg,es:data_seg,ss:stack_seg
main proc far
start:
    mov ax,data_seg
      mov ds,ax                   ;初始化数据段
      mov es,ax                   ;初始化附加段

      cld                         ;df=0
      lea di,tel_tab              ;名字表的首地址放入di

      lea dx,msg_count
      mov ah,9
      int 21h                     ;显示信息0:'How many names do you want to enter?'

again:call decibin                ;调用decibin(将输入的十进制次数转换成机器能识别的二进制数)

   cmp dx,2                    ;注意该条语句和下面的跳转语句的位置.计数器(记录名字数的位数)

     call crlf;回车换行

      je exit1                   ;一个有效字符都没输入,跳转要求重新输入.输入的为非法字符即非数字则不等输入完就跳出

      push bx
      cmp bx,50 ;
      ja  return                  ;输入的个数大于50出错跳出
      ;输入表中项数并保存在bx中

repeat:pop bx
       cmp namcount,bx     ;目前项数和要求输入的项数比较,名字数和bx比较
       je  choice                 ;如果所有项都输入完毕则跳到choice排序
       push bx ;stor_name会用到bx,先保存

       lea dx,msg_inputnam
       mov ah,9
       int 21h ;要求输入名字
       call input_name            ;调用input_name
       cmp ncurlen,0               ;没有输入了则开始排序,输入名字的字符数为0跳转
       je  choice
       call stor_name
       call input_phone           ;调用input_phone
       jmp  repeat ;由于tel_tab是顺序连续存储,每一次输入一项后,di即指向下一项的开始,所以无需调整


choice:cmp namcount,1
       jb  return1                ;表中项数小于1则要求输入
       call name_sort             ;不小于调用name_sort



IP属地:河北1楼2006-01-18 10:04回复

    rotate:lea dx,msg_inquire ;输出'Do you want a telephone number?(Y/N)'
           mov ah,9
           int 21h                    ;显示是否查找电话号码
           mov ah,1
           int 21h                    ;由键盘输入‘Y’或‘N’

           cmp al,'y'
           je loop0
           cmp al,'Y'
           jne exit                   ;不为‘Y'或'y'跳出转至exit
           jmp loop0;为‘Y'回车、换行

                      

    loop0: call crlf
      lea dx,msg_sname ;'name?'
           mov ah,9
           int 21h                    ;显示要查询电话的姓名

           call input_name            ;输入姓名
           call name_search           ;调用name_search
           jmp rotate                 ;返回查找另一个电话

    insert: call crlf
      call stor_name
            call input_phone
            ;call printline
            ;cmp namcount,1
            ;jb  return1                ;表中项数小于1则要求输入
            call name_sort             ;不小于调用name_sort      
            call printline
           jmp rotate


     exit1: lea dx,msg_illch ;'Error:The number of your enter is not allowed! Please intput the number again!'
           mov ah,9
           int 21h

           jmp again

    return:lea dx,msg_illcount ;'Error:The number of your enter exceed the limit of 50! Plesae input the number again!'
           mov ah,9
           int 21h

           jmp again

    return1:lea dx,msg_inputerr ;输出'Error:Input error!,please input a name!'
            mov ah,9
            int 21h               ;没有输入名字

            jmp repeat            ;出错跳转

    exit:  call printline ;输出排序结果

      ;输入任意字符退出
           mov ah,7
           int 21h
           mov ax,4c00h
           int 21h
     main endp                   ;主程序结束


    name_search proc near
    ;在表中顺序查找输入的名字
            lea di,tel_tab           ;把输入的名字首地址放入di
            push di                  ;保存名字表首址,di为指向tel_tab表项的指针
            mov bx,namcount           ;名字的个数放bx
    loop1:  lea si,namefld           ;名字的缓存区首地址放入si
            mov cx,20
            repe cmpsb               ;连续查找匹配名字
            je  found                ;找到跳转found
            pop di                   ;没找到di出栈
            add di,28               ;把查找转到下一个名字
            push di
            dec bx
            jnz loop1                ;循环查找

            lea dx,msg_nomatch
            mov ah,9
            int 21h                   ;一直没找到则显示没有找到名字

            mov ah,1
           int 21h                    ;由键盘输入‘Y’或‘N’
            cmp al,'y'

            je insert
            ;cmp al,'Y' ;此时di应指向插入位置

            jne loop0                   ;不为‘Y'或'y'跳转至重新输入名字查找
      ;jmp insert

    found:  pop di
      lea dx,msg_outtitle
            mov ah,9
            int 21h

            mov si,di ;把要找到的内容暂存在namtemp中
            lea di,namtemp
            mov cx,28
            rep movsb

            lea dx,namtemp
            mov ah,9
            int 21h                  ;显示查到的姓名和电话号码
            ret
    name_search endp

    decibin proc near
    ;键盘输入十进制数转换成二进制数
      mov bx,0         ;bx清零
            mov dx,2         ;输入数的位数置2

    


    IP属地:河北2楼2006-01-18 10:04
    回复
      2025-05-20 04:45:16
      广告
      newchar:
              mov ah,1
              int 21h          ;一号功能调用(输入字符并回显)

              sub al,30h
              jb  exit2        ;非数字退出
              cmp al,9
              ja  exit2        ;大于9退出(十进位制数每位0-9)
              cbw              ;字节转换成字(al->ax)
              xchg ax,bx       ;交换ax、bx
              mov cx,10
              push dx
              mul cx           ;先保存,dx×10
              xchg ax,bx       ;再将ax、bx交换回
              add  bx,ax
              pop  dx
              dec  dx
              jnz  newchar     ;位数不为0跳转

      exit2: ret
      decibin endp             ;结束

      input_name proc near     ;子程序(输入名字)
      ;接受输入字符并放入缓冲区
              lea dx,nameitem
              mov ah,0ah
              int 21h          ;输入名字并送入缓存区

              call crlf       ;回车、换行

              mov bh,0
              mov bl,ncurlen   ;把名字的字符个数放入bx低位
              mov cx,21 ;置循环次数
              sub cx,bx

      repeat1:mov namefld[bx],20h
              inc bx
              loop repeat1      ;输入的名字为20字节,不足的用空格补足
              ret
      input_name endp

      stor_name proc near      ;子程序(传送名字的每个字母到si)
      ;需要事先已设置好di
        inc namcount
              cld               ;df=0(从小到大)
              lea si,namefld
              mov cx,20
              rep movsb         ;重复传送串名字(以字节为单位),直至送满20即cx=0 ,di指向tel_tab
              ret
      stor_name endp

      input_phone proc near     ;子程序(输入电话号码)
      ;需要事先已设置好di
              lea dx,msg_inputnum
              mov ah,9
              int 21h            ;显示要求输入电话号码

              lea dx,phoneitem
              mov ah,10
              int 21h            ;输入电话号码并送入缓存区
              
              mov bh,0
              mov bl,pcurlen
              mov cx,9 ;置循环次数
              sub cx,bx

      repeat2:mov phonefld[bx],20h
              inc bx
              loop repeat2      ;输入的电话为8字节,不足的用空格补足

              call crlf

              cld                ;df=0
              lea si,phonefld
              mov cx,8
              rep movsb          ;把输入的号码存入namtab表中,重复传送串电话号码(以字节为单位)
              ret
      input_phone endp

      name_sort proc near          ;子程序
      ;有交换标志的冒泡排序,需要设置di
        push di
        push ax
        push bx
              cmp namcount,1
              jz  exit4            ;比较名字个数(只有一个名字即退出)

      s1:     mov swap,0
        sub di,56;di指针后移两个表项,第一次指向倒数第二项,以后每跑一趟前移一项
        mov addend,di ;重新计算表尾指针
        lea si,tel_tab

      s2:     mov cx,20 ;置循环计数值
              mov di,si
              add di,28 ;di->后项,si->前项
              mov ax,di ;后项保存在ax
              mov bx,si ;前项保存在bx
              repe cmpsb ;源-目标,即前项如果大于后项,交换;
              jbe s3
              call exchange

      s3:     mov si,ax
              cmp si,addend
              jbe s2 ;是否已到namtab表尾,如果没到继续循环
              cmp swap,0 ;如果有交换,继续下一趟
              jnz s1

      exit4:  pop bx
        pop ax
        pop di
        ret

      name_sort endp

      exchange proc near
      ;交换tel_tab中di,si所指表项的内容,前项保存在bx
              mov cx,28
              lea di,namtemp
              mov si,bx
              rep movsb
              
              mov cx,28
              mov di,bx
              rep movsb
              
              mov cx,28
              lea si,namtemp
              rep movsb
              
              mov swap,1
              ret
      exchange endp

      printline proc near
      ;输出排序结果,不需要设置di,会改变di值
        push di
        push namcount;printline会被多次调用,保存namcount的值
        
              call crlf               ;回车、换行

              lea dx,msg_result ;'The result of sort is as follows:'
              mov ah,9
              int 21h                ;显示升序输出姓名、电话

              lea si,tel_tab
      loop2:  lea di,namtemp
              mov cx,28 ;si每一次loop2会自动修正
              rep movsb              ;循环传送姓名、电话至输满27字节即cx=0
              lea dx,namtemp
              mov ah,9
              int 21h                ;显示姓名、电话
              dec namcount            ;名字数减1
              jnz loop2              ;没输完则循环输出

              pop namcount
              pop di
              ret
      printline endp

      deciasc proc near
      ;把10进制数转换成相应的ASCII码,digit in bl
      mov ch,10d
      mov cl,10d
      ;mov dh,3d;

      re:
       ;判断退出条件
       cmp ch,0
       je quit

       ;取每一10进制位上的数字
       mov al,bl;
       cbw
       div ch;
       mov bl,ah;余数继续除相应权,取相应位的10进制数字

       call printit
       ;a1a2a3... 递推:x=an-1*10+an
       ;mov dl,al;商暂存在bl中
       ;mov dh,ah;余数暂存在dh中
       ;mov bh,0d;
       ;mov ax,bx
       ;mul cl
       ;mov bl,al
       ;add bl,dl

       ;除数ch=ch/10
       mov al,ch
       cbw
       div cl
       mov ch,al
       ;dec dh
       jmp re

      quit:
       ret
      deciasc endp

      printit  proc near
      ;输出1位数字对应的ASCII码,binary number in al
       add al,30h
       mov dl,al
       mov ah,2
       int 21h
       ret;ret不能少!
      printit  endp

      crlf proc near
      ;输出回车换行
        mov dl,0dh  ;mov指令不影响标志位  
              mov ah,2
              int 21h
              mov dl,0ah
              mov ah,2
              int 21h
              ret
      crlf endp

      code_seg ends
        end start
      


      IP属地:河北3楼2006-01-18 10:04
      回复
        • 61.177.142.*
        我用啦
        呵呵


        4楼2006-01-19 08:50
        回复


          IP属地:河北5楼2006-01-23 00:06
          回复
            • 58.49.186.*
            谢谢


            6楼2007-01-20 23:47
            回复
              好东西~~~


              7楼2007-03-02 13:11
              回复
                • 125.67.144.*
                能说下设计思路吗????谢谢诶


                8楼2008-01-13 11:08
                回复
                  2025-05-20 04:39:16
                  广告
                  • 125.73.56.*
                  救世


                  9楼2008-05-08 19:59
                  回复
                    • 116.209.233.*
                    Thanks!


                    10楼2008-05-19 20:35
                    回复
                      • 222.241.243.*
                      怎么还是有点问题


                      11楼2008-06-17 19:09
                      回复
                        • 222.215.98.*
                        四川省语委办公室电话号码


                        12楼2008-10-14 19:03
                        回复
                          • 213.197.27.*
                          8楼不会自己看么


                          13楼2008-11-23 15:02
                          回复
                            • 222.201.144.*
                            爱死你了


                            14楼2008-12-14 09:56
                            回复
                              2025-05-20 04:33:16
                              广告
                              • 60.31.74.*
                              太感谢了 !


                              15楼2008-12-21 09:34
                              回复