⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 1.asm

📁 一个简单的汇编程序,电话号码本的编辑和查找
💻 ASM
字号:
DATAS 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 order you want to input?',13,10,'$' 
   msg_illcount db 'Error:The order of your enter exceed the limit of 50! Plesae input the number again!',13,10,'$' 
   msg_illch db 'Error:The order 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 to find 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,'$' 
   
DATAS ENDS
;-----------------------------------------------------------------------------------------------------------
STACKS SEGMENT para stack 'stack'
    dw 256 dup(0) 
STACKS ENDS

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,ES:DATAS,SS:STACKS
main proc far    ;主程序段
START:
    MOV AX,DATAS
    MOV DS,AX
    MOV ES,AX      ;初始化附加段     
    cld                         ;df=0 
    lea di,tel_tab              ;名字表的首地址放入di
    
    lea dx,msg_count 
    mov ah,9 
    int 21h                     
again:call decibin                ;调用decibin
    cmp dx,2                   
    call crlf 
    je exit1                   ;一个有效字符都没输入,跳转要求重新输入.输入的为非法字符即非数字则不等输入完就跳出 
    push bx 
    cmp bx,50 ; 
    ja  return                  ;输入的个数大于50出错跳出 
    
repeat0:
       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  repeat0 ;由于tel_tab是顺序连续存储,每一次输入一项后,di即指向下一项的开始,所以无需调整 

choice:cmp namcount,1 
       jb  return1                ;表中项数小于1则要求输入 
       call name_sort             ;不小于调用name_sort 
rotate:lea dx,msg_inquire ;输出'Do you want to find 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 ;输入顺序数不合法,重新输入 
       mov ah,9 
       int 21h 

       jmp again 

return:lea dx,msg_illcount ;输入顺序数超出号码本容量,重新输入
       mov ah,9 
       int 21h 

       jmp again 

return1:lea dx,msg_inputerr ;输入错误,重新输入姓名 
        mov ah,9 
        int 21h               ;没有输入名字 

        jmp repeat0            ;出错跳转 

exit:  call printline ;输出排序结果 
       mov ah,7 
       int 21h
       jmp main   
 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     ;十进制转化为2进制 ,并保存到bx中
  mov bx,0         ;bx清零 
        mov dx,2         ;输入数的位数置2 
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)  
  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     ;子程序(输入电话号码) 
        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          ;子程序(进行排序)
  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   ;保存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 

re:       ;判断退出条件 
 cmp ch,0 
 je quit  
 mov al,bl; 
 cbw 
 div ch; 
 mov bl,ah

 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 
printit  endp 
;---------------------------------------------------------------------------------------------------
crlf proc near 
        mov dl,0dh   
        mov ah,2 
        int 21h 
        mov dl,0ah 
        mov ah,2 
        int 21h 
        ret 
crlf endp

CODES ENDS
    END START







⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -