• 汇编语言之判断回文数


    题目描述:

      打印回文数。如果一个数从左边和从右边读都是相同的数,就称它为回文数,例如383。求出500 以内的回文数并输出显示。要求:提示数据范围为0-500;Enter键,换行显示结果。

    基本功能

      每输入一个数,都判断是不是回文数(同时伴随着溢出和错误输入判断);若出现溢出或者是错误输入时,程序提示重新输入。

    拓展功能:

      每输入一个1到500的数,若该数是回文数,则输出打印其中0到该数内的所有回文数;若不是回文数,则输出提示不是回文数,并且结束程序。

    基本功能代码:

    enterline macro        ;定义回车换行的宏指令
        mov dl,13
        mov ah,2
        int 21h
        mov dl,10
        mov ah,2
        int 21h
    endm
    
    DATAS SEGMENT
        input db 'Please input a number between 0 and 500:$'
        output1 db 'Convertion Success!$' 
        err db 'Illegal input! Please Try Again$'
        out1 db 'Sorry, the number you entered is more than 500, please try again$'
        buf db 10,?,10 dup(0)    ;定义键盘接收字符缓冲区,最多接收9个字符
        len dw ?        ;记录输入的数的长度
        nop1 db 'The number you entered is not palindrome, bye$'
        sum dw ?
        space db ' '    ;空格
        flag db 0
        
        
        test1 db '333$'
        ;此处输入数据段代码  
    DATAS ENDS
    
    STACKS SEGMENT
        ;此处输入堆栈段代码
    STACKS ENDS
    
    CODES SEGMENT
        ASSUME CS:CODES,DS:DATAS,SS:STACKS
    START:
        MOV AX,DATAS
        MOV DS,AX
        ;此处输入代码段代码
        
    begin:
        lea dx,input    ;给出输入提示
        mov ah,9
        int 21h
        enterline        ;回车换行
        
        lea dx,buf        ;从键盘接收输入数值放入buf缓冲区(输入操作)
        mov ah,10
        int 21h
        enterline        ;回车换行
           
           push bx            ;入栈保护
           push cx
           push dx
           push si                
           call ascii_num
           pop si            ;退栈
           pop dx
           pop cx
           pop bx
    
    ;接下来是回文数的检测  考虑直接对字符进行回文数的检测
        
        jmp judge            ;判断输入的数长度,结果存在cx中,si存入检测的数
      
    judgeovr:
        
        cmp flag,0            ;标志是否为输出的那个数
        je firstjudge  
        
    
    firstjudge:    
        mov flag,1
        mov si,0      
        
        cmp cx,1
        je loop_num 
        
        
        cmp cx,2
        je len2
        
        cmp cx,3
        je len3
        
        
    
    len2:
     
     lea dx,test1
        mov ah,9
        int 21h
        enterline
    
        
        xor ax,ax
        xor dx,dx
        mov ax,sum
        mov bx,10
        div bx
         cmp ax,dx
         je loop_num
         
         jmp not1        ;判断出该数不是回文数
         
    len3:
        
        xor ax,ax
        xor dx,dx
        xor di,di
        mov ax,sum
        mov bx,100
        div bx
         mov di,ax
         mov ax,dx
         xor dx,dx
         mov bx,10
         div bx
         cmp di,dx
         je loop_num    
         
         jmp not1        ;判断出该数不是回文数
     
       
    loop_num:
        lea dx,output1
        mov ah,9
        int 21h
        jmp stop
    
    
    num_ascii:
        mov ax,si;(有效数值为0~65535)  待转换数放置于AX寄存器中
        mov bx,100            ;初始数位权值为100
        
    cov1:xor dx,dx            ;将dx:ax中的数值除以权值
        div bx
        mov cx,dx            ;余数备份到CX寄存器中
        
        cmp flag,0            ;检测是否曾遇到非0商值
        jne nor1            ;如遇到过,则不管商是否为0都输出显示
        cmp ax,0            ;如未遇到过,则检测商是否为0
        je cont                ;为0则不输出显示
        
    nor1:
        mov dl,al            ;将商转换为ascii码输出显示
        add dl,30h
        mov ah,2
        int 21h
        
        mov flag,1            ;曾遇到非0商,则将标志置1
        
    cont:
        cmp bx,10            ;检测权值是否已经修改到十位了
        je outer            ;如果相等,则完成最后的个位数输出显示
        
        xor dx,dx            ;将数位权值除以10
        mov ax,bx
        mov bx,10
        div bx
        mov bx,ax
        
        mov ax,cx            ;将备份的余数送入AX
        jmp cov1                ;继续循环
       
    outer:
        mov dl,cl            ;最后的个位数变为ascii码输出显示
        add dl,30h
        mov ah,2
        int 21h   
        
        mov dl,space
        mov ah,2
        int 21h
        
        jmp loop_num
    
       
    not1:                ;不是回文数
        lea dx,nop1
        mov ah,9
        int 21h
        enterline 
        
        jmp stop         ;如出错则返回起始点重新输入 
        
    error:                ;给出错误提示(输入不规范)
        lea dx,err
        mov ah,9
        int 21h
        enterline 
        
        jmp begin         ;如出错则返回起始点重新输入  
      
    yichu:                ;超过500范围的提示
        lea dx,out1
        mov ah,9
        int 21h
        enterline 
        
        jmp begin         ;如出错则返回起始点重新输入 
        
    judge:
    
        xor ax,ax
        xor dx,dx
        xor bx,bx
        xor cx,cx
        
        mov si,sum
        mov cx,1            ;最初长度赋值为1
        
        
        mov ax,si            ;将检测的数赋值给ax
        mov bx,10            ;除数赋值10
        div bx
        cmp ax,0            ;相等就跳走
        je judgeovr
        
        mov cx,2
        xor dx,dx
        mov ax,si            ;将检测的数赋值给ax
        mov bx,100            ;除数赋值10
        div bx
        
        cmp ax,0
        je judgeovr
        
        
        mov cx,3
        jmp judgeovr
        
        
    stop:
        MOV AH,4CH
        INT 21H
    
    
    ascii_num PROC        ;将字符串转成数字的子程序
    
        mov cl,buf+1    ;获取实际键入字符数,置于CX寄存器中
        xor ch,ch        ;ch清0
        mov len,cx        ;这里把长度保存下来方便后面使用
        
        xor di,di        ;累加器清0
        xor dx,dx        ;dX寄存器清0
        mov bx,1        ;由于从个位数开始算起,因而将所乘权值设为1
        
        lea si,buf+2    ;将si指向接收到的第1个字符位置
        add si,cx        ;因为从个位算起,所以将si指向最后1个接收到的个位数
        dec si            ;往回减1使其指向字串最后一个元素
    
    cov:mov al,[si]        ;取出个位数给al
        cmp al,'0'        ;边界检查:如果输入不是0-9的数字,就报错
        jb error
        cmp al,'9'
        ja error
    
        sub al,30h        ;将al中的ascii码转为数字
        xor ah,ah
        mul bx            ;乘以所处数位的权值
        cmp dx,0        ;判断结果是否超出16位数范围,如超出则报错
        jne error
        
        add di,ax        ;将形成的数值放在累加器di中
        jc error        ;如数值超过16位数范围报错
        
        cmp di,500
        ja yichu
        mov sum,di
        
            
        mov ax,bx        ;将BX中的数位权值乘以10
        mov bx,10
        mul bx
        mov bx,ax
        
        dec si            ;si指针减1,指向前一数位
        loop cov        ;按CX中的字符个数计数循环
       
           mov ax,di        ;将最终转换结果从di中放置到ax中
    EXIT:
        RET
    ascii_num ENDP
    
    
    CODES ENDS
        END START

    拓展功能代码:

      1 enterline macro        ;定义回车换行的宏指令
      2     mov dl,13
      3     mov ah,2
      4     int 21h
      5     mov dl,10
      6     mov ah,2
      7     int 21h
      8 endm
      9 
     10 DATAS SEGMENT
     11     input db 'Please input a number between 0 and 500:$'
     12     err db 'Illegal input! Please Try Again$'
     13     out1 db 'Sorry, the number you entered is more than 500, please try again$'
     14     buf db 10,?,10 dup(0)    ;定义键盘接收字符缓冲区,最多接收9个字符
     15     
     16     nop1 db 'The number you entered is not palindrome, bye$'
     17     sum dw ?
     18     space db ' '    ;空格
     19     flag db 0            ;用于不输出前导0的标志
     20     ff db 0                ;用于标记是否为第一次回文数判断
     21     zero db 0            ;标志0是否输出过
     22     
     23     ;此处输入数据段代码  
     24 DATAS ENDS
     25 
     26 STACKS SEGMENT
     27     ;此处输入堆栈段代码
     28 STACKS ENDS
     29 
     30 CODES SEGMENT
     31     ASSUME CS:CODES,DS:DATAS,SS:STACKS
     32 START:
     33     MOV AX,DATAS
     34     MOV DS,AX
     35     ;此处输入代码段代码
     36     
     37 begin:
     38     lea dx,input    ;给出输入提示
     39     mov ah,9
     40     int 21h
     41     enterline        ;回车换行
     42     
     43     lea dx,buf        ;从键盘接收输入数值放入buf缓冲区(输入操作)
     44     mov ah,10
     45     int 21h
     46     enterline        ;回车换行
     47        
     48        push bx            ;入栈保护
     49        push cx
     50        push dx
     51        push si                
     52        call ascii_num    ;调用子程序输入数据
     53        pop si            ;退栈
     54        pop dx
     55        pop cx
     56        pop bx
     57 
     58     mov si,sum            ;将输入的数的值先复制给si
     59     call judge            ;判断输入的数长度,结果存在cx中,si是待检测的数
     60     
     61     
     62 judgeovr:                ;第二次及以后的回文数判断
     63     cmp ff,0            ;标志是否为输出的那个数
     64     je firstjudge  
     65     
     66     cmp cx,1            ;数只有一位时直接输出 
     67     je num_ascii         
     68     cmp cx,2            ;数有两位时跳转到两位数的回文判断
     69     je len22
     70     cmp cx,3            ;数有三位时跳转到三位数的回文判断
     71     je len33
     72 
     73 len22:                    ;两位数的回文判断,判断个位十位是否相同
     74     xor ax,ax
     75     xor dx,dx
     76     mov ax,si
     77     mov bx,10
     78     div bx
     79      cmp ax,dx
     80      je num_ascii
     81      
     82      jmp loop_num        ;判断出该数不是回文数,跳回loop_num去取下一个数
     83     
     84 len33:                    ;三位数的回文判断,判断百位个位是否相同
     85     xor ax,ax
     86     xor dx,dx
     87     xor di,di
     88     mov ax,si
     89     mov bx,100
     90     div bx
     91      mov di,ax
     92      mov ax,dx
     93      xor dx,dx
     94      mov bx,10
     95      div bx
     96      cmp di,dx
     97      je num_ascii
     98      
     99      jmp loop_num        ;判断出该数不是回文数,跳回loop_num去取下一个数
    100 
    101 
    102 firstjudge:                ;对输入的数进行第一次的回文判断
    103     mov ff,1
    104     mov si,0              ;si从0开始,方便后面inc 
    105     
    106     cmp cx,1            ;数只有一位时直接跳转去循环,代表输入的数是回文数            
    107     je loop_num                                          
    108     cmp cx,2            ;数有两位时跳转到两位数的回文判断
    109     je len2                                              
    110     cmp cx,3            ;数有三位时跳转到三位数的回文判断
    111     je len3    
    112 
    113 len2:                    ;两位数的回文判断,判断个位十位是否相同
    114     xor ax,ax
    115     xor dx,dx
    116     mov ax,sum            ;将输入的值赋给ax去判断
    117     mov bx,10
    118     div bx
    119      cmp ax,dx
    120      je loop_num            ;判断该数是回文数,跳转循环
    121      
    122      jmp not1            ;判断出该数不是回文数,跳转notq
    123      
    124 len3:                    ;三位数的回文判断,判断百位各位是否相同
    125     xor ax,ax
    126     xor dx,dx
    127     xor di,di
    128     mov ax,sum            ;将输入的值赋给ax去判断
    129     mov bx,100
    130     div bx
    131      mov di,ax
    132      mov ax,dx
    133      xor dx,dx
    134      mov bx,10
    135      div bx
    136      cmp di,dx
    137      je loop_num            ;判断该数是回文数,跳转循环
    138      
    139      jmp not1            ;判断出该数不是回文数,跳转not1
    140  
    141    
    142 loop_num:                ;循环:代表输入的数已经是回文数,接下来循环从0—输入的数的回文数打印
    143     
    144     inc si                ;每次都去判断,si的变化范围是0—输入的数,每次加1
    145     cmp si,sum            ;当大于输入的数时跳转停止
    146     ja stop
    147     
    148     call judge            ;每次si加1后,都要去判断si的长度,其中cx中存长度
    149                         ;judge判断完长度后,会自动跳转判断回文数和打印数
    150     
    151     jmp loop_num        ;不断循环
    152     
    153 zz:                        ;该段程序是解决输出0的问题
    154     mov zero,1            ;0输出过
    155     
    156     mov dl,'0'
    157     mov ah,2
    158     int 21h
    159         
    160     mov dl,space        ;输出空格
    161     mov ah,2
    162     int 21h
    163     
    164     jmp num_ascii        ;输完0后再开始从1开始输出
    165 
    166 num_ascii:                ;将num转为ascii
    167     cmp zero,0            ;判断0是否输出过,没输出就去输出0
    168     je zz
    169 
    170     mov ax,si            ;将每次循环计数的si赋值ax去输出
    171     mov bx,10            ;初始数位权值为10
    172     cmp cx,3            ;若为3位数,则赋权为100
    173     je cx_3
    174     
    175 cov1:xor dx,dx            ;将dx:ax中的数值除以权值
    176     div bx
    177     mov cx,dx            ;余数备份到CX寄存器中
    178     
    179     cmp flag,0            ;检测是否曾遇到非0商值
    180     jne nor1            ;如遇到过,则不管商是否为0都输出显示
    181     cmp ax,0            ;如未遇到过,则检测商是否为0
    182     je cont                ;为0则不输出显示
    183     
    184 nor1:
    185     mov dl,al            ;将商转换为ascii码输出显示
    186     add dl,30h
    187     mov ah,2
    188     int 21h
    189     
    190     mov flag,1            ;曾遇到非0商,则将标志置1
    191     
    192 cont:
    193     cmp bx,10            ;检测权值是否已经修改到十位了
    194     je outer            ;如果相等,则完成最后的个位数输出显示
    195     
    196     xor dx,dx            ;将数位权值除以10
    197     mov ax,bx
    198     mov bx,10
    199     div bx
    200     mov bx,ax
    201     
    202     mov ax,cx            ;将备份的余数送入AX
    203     jmp cov1                ;继续循环
    204    
    205 outer:
    206     mov dl,cl            ;最后的个位数变为ascii码输出显示
    207     add dl,30h
    208     mov ah,2
    209     int 21h   
    210     
    211     mov dl,space        ;输出空格
    212     mov ah,2
    213     int 21h
    214     
    215     jmp loop_num        ;每次输出完一个数后,跳回循环去取下一个数
    216 
    217   
    218 
    219 cx_3:
    220     mov bx,100        ;赋权值为100
    221     jmp cov1
    222      
    223 not1:                ;不是回文数
    224     lea dx,nop1
    225     mov ah,9
    226     int 21h
    227     enterline 
    228     
    229     jmp stop         ;如输入不是回文数则返回起始点重新输入 
    230     
    231 error:                ;给出错误提示(输入不规范)
    232     lea dx,err
    233     mov ah,9
    234     int 21h
    235     enterline 
    236     
    237     jmp begin         ;如出错则返回起始点重新输入  
    238   
    239 yichu:                ;超过500范围的提示
    240     lea dx,out1
    241     mov ah,9
    242     int 21h
    243     enterline 
    244     
    245     jmp begin         ;如出错则返回起始点重新输入 
    246    
    247 stop:                
    248     MOV AH,4CH
    249     INT 21H
    250      
    251 judge PROC                ;判断位数的子程序
    252     xor ax,ax
    253     xor dx,dx
    254     xor bx,bx
    255     xor cx,cx
    256     mov cx,1            ;最初长度赋值为1
    257     
    258     mov ax,si            ;将检测的数赋值给ax
    259     mov bx,10            ;除数赋值10
    260     div bx
    261     cmp ax,0            ;商等于0就跳转,去判断回文数
    262     je judgeovr
    263     mov cx,2
    264     
    265     xor dx,dx
    266     mov ax,si            ;将检测的数赋值给ax
    267     mov bx,100            ;除数赋值10
    268     div bx
    269     cmp ax,0            ;商等于0就跳转,去判断回文数
    270     je judgeovr
    271     
    272     mov cx,3            ;表明当前为数应该为三
    273     jmp judgeovr        ;去判断回文数
    274 
    275 EXIT:
    276     RET
    277 judge ENDP
    278 
    279 ascii_num PROC        ;将字符串转成数字的子程序
    280 
    281     mov cl,buf+1    ;获取实际键入字符数,置于CX寄存器中
    282     xor ch,ch        ;ch清0
    283  
    284     xor di,di        ;累加器清0
    285     xor dx,dx        ;dX寄存器清0
    286     mov bx,1        ;由于从个位数开始算起,因而将所乘权值设为1
    287     
    288     lea si,buf+2    ;将si指向接收到的第1个字符位置
    289     add si,cx        ;因为从个位算起,所以将si指向最后1个接收到的个位数
    290     dec si            ;往回减1使其指向字串最后一个元素
    291 
    292 cov:mov al,[si]        ;取出个位数给al
    293     cmp al,'0'        ;边界检查:如果输入不是0-9的数字,就报错
    294     jb error
    295     cmp al,'9'
    296     ja error
    297 
    298     sub al,30h        ;将al中的ascii码转为数字
    299     xor ah,ah
    300     mul bx            ;乘以所处数位的权值
    301     cmp dx,0        ;判断结果是否超出16位数范围,如超出则报错
    302     jne error
    303     
    304     add di,ax        ;将形成的数值放在累加器di中
    305     jc error        ;如数值超过16位数范围报错
    306     
    307     cmp di,500        ;超过500的判断
    308     ja yichu
    309         
    310     mov ax,bx        ;将BX中的数位权值乘以10
    311     mov bx,10
    312     mul bx
    313     mov bx,ax
    314     
    315     dec si            ;si指针减1,指向前一数位
    316     loop cov        ;按CX中的字符个数计数循环
    317    
    318        mov sum,di        ;将最终转换结果从di中放置到sum中
    319 EXIT:
    320     RET
    321 ascii_num ENDP
    322 
    323 CODES ENDS
    324     END START

       

  • 相关阅读:
    [NOTE]常用Linux命令总结[Thx for commandlinefu]
    [原]隧道Proxy原理详解(基于Node.js)
    [转]MySQL索引详解(1)
    [QA]服务端进程模型
    [转]MySQL索引详解(2)
    非动态规划实现LCS算法
    Java里线程安全的有界容器的实现
    maven历史版本下载
    JDK9下载
    maven排除依赖和添加本地依赖
  • 原文地址:https://www.cnblogs.com/xwh-blogs/p/12576877.html
Copyright © 2020-2023  润新知