匯編語言之判斷回文數


題目描述:

  打印回文數。如果一個數從左邊和從右邊讀都是相同的數,就稱它為回文數,例如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

 

 

 

   


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM