匯編語言之加法練習程序


題目描述:

  加法練習程序。要求:從鍵盤輸入百位數以內的加法算式,並提示輸入答案,若正確給出正確提示,若錯誤給出錯誤提示,並提示輸入答案;按R 鍵繼續輸入下一題,按Q 鍵返回DOS。
 
擴展功能:
  支持多位加數相加
 
代碼:
  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     ;此處輸入數據段代碼 
 12     info db'Please enter an addition expression, such as A + B$' 
 13     err db 'Illegal input! Please Try Again$'
 14     again db'Invalid input, try again.$'
 15     overout db'The number overflowed, try again$'
 16     overout1 db'The result overflowed, try again$'
 17     inn db'Please enter your answer$'
 18     win db'Congratulations, the answer is right$'
 19     note db'Note: press the r key to continue to input the next question, and press the q key to exit the program$'
 20     lose1 db'Sorry, your answer is wrong. You have 2 more chances$'
 21     lose2 db'Sorry, your answer is wrong. You have 1 more chances$'
 22     lose3 db'Sorry, your answer is wrong. The right answer is $'
 23     
 24     result dw 0        ;用於存放最終結果
 25     errtime db ?    ;答案錯誤次數
 26     flag db ?
 27  
 28     buf db 30,?,30 dup(0)    ;定義鍵盤接收字符緩沖區,最多接收19個字符
 29     ff db ?        ;輸出的判斷前導0的標志
 30     input db ?    ;儲存輸入的按鍵
 31     
 32     op1 dw ?    ;定義兩個操作數
 33     op2 dw ?
 34 DATAS ENDS
 35 
 36 STACKS SEGMENT
 37     ;此處輸入堆棧段代碼
 38 STACKS ENDS
 39 
 40 CODES SEGMENT
 41     ASSUME CS:CODES,DS:DATAS,SS:STACKS
 42 START:
 43     MOV AX,DATAS
 44     MOV DS,AX
 45     ;此處輸入代碼段代碼
 46     
 47 main:                ;加法模塊        ;設計完加法子程序后把下面這部分也封裝進去
 48     lea dx,info        ;提示信息
 49     mov ah,9
 50     int 21h
 51     enterline
 52     
 53     mov errtime,3    ;允許犯錯的次數
 54 
 55     call inputi        ;調用輸入的子程序,輸入公式
 56     
 57     cmp flag,1
 58     je main            ;由於錯誤輸入跳回a1重新進行加法操作
 59     cmp flag,2
 60     je main            ;由於溢出跳回a1重新輸入
 61     
 62 
 63 shuru:    
 64     lea dx,inn        ;提示輸入信息
 65     mov ah,9
 66     int 21h
 67     enterline
 68     
 69     call input2        ;調用輸入的子程序,輸入答案
 70     cmp flag,1
 71     je shuru            ;由於錯誤輸入跳回shuru
 72     cmp flag,2
 73     je shuru            ;由於錯誤輸入跳回shuru
 74     
 75     mov bx,result        ;判斷輸入的答案是否正確
 76     cmp bx,op1
 77     je correct
 78     
 79     dec errtime        ;嘗試次數減1
 80     cmp errtime,2    ;剩余兩次機會
 81     je error1
 82     cmp errtime,1    ;剩余1次機會
 83     je error2
 84     cmp errtime,0    ;不剩機會
 85     je error3
 86     
 87 error1:
 88     lea dx,lose1        ;提示信息
 89     mov ah,9
 90     int 21h
 91     enterline
 92     jmp shuru        ;執行完后跳回主菜單
 93 error2:
 94     lea dx,lose2        ;提示信息
 95     mov ah,9
 96     int 21h
 97     enterline
 98     jmp shuru        ;執行完后跳回主菜單
 99 error3:
100     lea dx,lose3        ;提示信息
101     mov ah,9
102     int 21h
103     mov bx,result        ;result是正確的和
104     call outi            ;輸出正確結果,結束此題
105     enterline
106 
107 judge1:                ;結果錯誤時的按鍵提示
108     lea dx,note        ;提示信息
109     mov ah,9
110     int 21h
111     enterline
112 
113     call judge        ;判斷輸入的鍵是什么鍵
114     enterline
115     cmp input,'r'
116     je main
117     cmp input,'q'
118     je stop
119     
120     jmp judge1
121 correct:            ;表示結果正確
122     lea dx,win        ;提示信息
123     mov ah,9
124     int 21h
125     enterline
126 
127 judge2:                ;結果正確時的按鍵提示
128     lea dx,note        ;提示信息
129     mov ah,9
130     int 21h
131     enterline
132     
133     call judge        ;判斷輸入的鍵是什么鍵
134     enterline
135     cmp input,'r'
136     je main
137     cmp input,'q'
138     je stop
139     jmp judge2
140 
141 stop:
142     MOV AH,4CH
143     INT 21H
144 
145 inputi proc            ;輸入子程序如下;專門用於存表達式的子程序
146     mov flag,0        ;初始化flag,用於標志錯誤或溢出
147     mov result,0    ;存放累加結果
148     
149     lea dx,buf        ;從鍵盤接收輸入數值放入buf緩沖區(輸入操作)
150     mov ah,10
151     int 21h
152     enterline        ;回車換行
153     
154     
155     mov cl,buf+1    ;獲取實際鍵入字符數,置於CX寄存器中
156     xor ch,ch        ;ch清0
157     
158     xor di,di        ;累加器清0
159     xor dx,dx        ;dX寄存器清0
160     mov bx,1        ;由於從個位數開始算起,因而將所乘權值設為1
161     
162     lea si,buf+2    ;將si指向接收到的第1個字符位置
163     add si,cx        ;因為從個位算起,所以將si指向最后1個接收到的個位數
164     dec si            ;往回減1使其指向字串最后一個元素
165 
166 ;cov是檢測並生成第一個數字的步驟
167 cov:mov al,[si]        ;取出個位數給al
168     cmp al,'+'        
169     jz addi        ;遇見空格則跳轉
170     
171     cmp al,'0'        ;邊界檢查:如果輸入不是0-9的數字,就報錯
172     jb wrong
173     cmp al,'9'
174     ja wrong
175     
176     sub al,30h        ;將al中的ascii碼轉為數字
177     xor ah,ah
178     mul bx            ;乘以所處數位的權值
179     cmp dx,0        ;判斷結果是否超出16位數范圍,如超出則報錯
180     jne yichu
181     
182     add di,ax        ;將形成的數值疊加放在累加器di中
183        cmp di,99
184     ja yichu        ;超過100報錯
185  
186     mov ax,bx        ;將BX中的數位權值擴大10倍,此處需要借助ax來實現
187     mov bx,10
188     mul bx
189     mov bx,ax
190     
191     dec si            ;si指針減1,指向前一數位
192     loop cov        ;按CX中的字符個數計數循環 
193     
194 lastadd:            ;從后往前數的最后一個加數,執行lastadd時loop已經結束
195     mov bx,result
196     add bx,di        ;存在bx寄存器中帶回
197     mov result,bx    ;備份結果在result中
198     jmp return      
199 addi:
200     mov bx,result    ;把當前累加值賦給bx
201     add bx,di        ;di表示當前某一個加數
202 
203     cmp bx,result    ;判斷是否溢出超過65535
204     jb yichu
205     mov result,bx    ;將結果存回result
206     
207     xor ax,ax
208     xor bx,bx
209     xor di,di        ;累加器清0
210     mov bx,1        ;由於下一個加數又從個位數開始算起,因而將所乘權值設為1
211     
212     dec si            ;向前移動一格位置
213     dec cx            ;遇到加號cx相應的減少1
214     jmp cov        ;結束后跳到cov部分
215         
216 wrong:            ;輸入錯誤
217     lea dx,err
218     mov ah,9
219     int 21h
220     mov flag,1
221     enterline
222     jmp return
223     
224 yichu:            ;加數超過100
225     mov flag,2
226     lea dx,overout
227     mov ah,9
228     int 21h
229     enterline
230     
231 return:
232     ret
233 inputi endp
234     
235     
236 input2 proc            ;專用於輸入純數字答案的子程序
237     mov flag,0
238     lea dx,buf        ;從鍵盤接收輸入數值放入buf緩沖區
239     mov ah,10
240     int 21h
241     enterline        ;回車換行
242     
243     mov cl,buf+1    ;獲取實際鍵入字符數,置於CX寄存器中
244     xor ch,ch
245     xor di,di        ;累加器清0
246     xor dx,dx        ;DX寄存器清0
247     mov bx,1        ;由於從個位數開始算起,因而將所乘權值設為1
248     lea si,buf+2    ;將si指向接收到的第1個字符位置
249     add si,cx        ;因為從個位算起,所以將si指向最后1個接收到的個位數
250     dec si
251     
252 cov:mov al,[si]        ;取出個位數給al
253     cmp al,'0'        ;邊界檢查:如果輸入不是0-9的數字,就報錯
254     jb wrong2
255     cmp al,'9'
256     ja wrong2
257 
258     sub al,30h        ;將al中的ascii碼轉為數字
259     xor ah,ah
260     mul bx            ;乘以所處數位的權值
261     cmp dx,0        ;判斷結果是否超出16位數范圍,如超出則報錯
262     jne over2
263     
264     add di,ax        ;將形成的數值放在累加器di中
265     jc over2        ;如數值超過16位數范圍報錯
266         
267     mov ax,bx        ;將BX中的數位權值乘以10
268     mov bx,10
269     mul bx
270     mov bx,ax
271     dec si            ;si指針減1,指向前一數位
272     loop cov        ;按CX中的字符個數計數循環
273     
274        mov op1,di        ;將結果儲存在op1中
275     jmp return2
276 
277 wrong2:                ;給出錯誤提示
278     lea dx,err
279     mov ah,9
280     int 21h
281     enterline
282     mov flag,1
283 
284     jmp return2 
285          
286 over2:
287     lea dx,overout
288     mov ah,9
289     int 21h
290     enterline
291     mov flag,2
292     
293 return2:
294     ret
295 input2 endp
296 
297 outi proc                ;輸出子程序
298     mov ax,bx            ;待輸出的數先存在bx里面,在給ax
299     mov bx,10000        ;初始數位權值為10000
300     mov ff,0            ;每次都賦初值0
301     
302 cov1:xor dx,dx            ;將dx:ax中的數值除以權值
303     div bx
304     mov cx,dx            ;余數備份到CX寄存器中
305     
306     cmp ff,0            ;檢測是否曾遇到非0商值
307     jne nor1            ;如遇到過,則不管商是否為0都輸出顯示
308     cmp ax,0            ;如未遇到過,則檢測商是否為0
309     je cont                ;為0則不輸出顯示    
310 nor1:
311     mov dl,al            ;將商轉換為ascii碼輸出顯示
312     add dl,30h
313     mov ah,2
314     int 21h
315     
316     mov ff,1            ;曾遇到非0商,則將標志置1
317 cont:
318     cmp bx,10            ;檢測權值是否已經修改到十位了
319     je outer            ;如果相等,則完成最后的個位數輸出顯示
320     
321     xor dx,dx            ;將數位權值除以10
322     mov ax,bx
323     mov bx,10
324     div bx
325     mov bx,ax
326  
327     mov ax,cx            ;將備份的余數送入AX
328     jmp cov1                ;繼續循環 
329 outer:
330     mov dl,cl            ;最后的個位數變為ascii碼輸出顯示
331     add dl,30h
332     mov ah,2
333     int 21h   
334     enterline
335 ret
336 outi endp
337 
338 judge proc
339     mov ah,1
340     int 21h
341     mov input,al        ;將儲存的字符給input
342 ret
343 judge endp
344 
345 
346 CODES ENDS
347     END START

 


免責聲明!

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



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