汇编语言之加法练习程序

2021-02-15 04:19

阅读:396

标签:定义   ext   div   start   专用   clear   错误提示   回车   inpu   

题目描述:

  加法练习程序。要求:从键盘输入百位数以内的加法算式,并提示输入答案,若正确给出正确提示,若错误给出错误提示,并提示输入答案;按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 dbPlease enter an addition expression, such as A + B$ 
 13     err db Illegal input! Please Try Again$
 14     again dbInvalid input, try again.$
 15     overout dbThe number overflowed, try again$
 16     overout1 dbThe result overflowed, try again$
 17     inn dbPlease enter your answer$
 18     win dbCongratulations, the answer is right$
 19     note dbNote: press the r key to continue to input the next question, and press the q key to exit the program$
 20     lose1 dbSorry, your answer is wrong. You have 2 more chances$
 21     lose2 dbSorry, your answer is wrong. You have 1 more chances$
 22     lose3 dbSorry, 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

 

汇编语言之加法练习程序

标签:定义   ext   div   start   专用   clear   错误提示   回车   inpu   

原文地址:https://www.cnblogs.com/xwh-blogs/p/12716861.html


评论


亲,登录后才可以留言!