汇编语言之加法练习程序
2021-02-15 04:19
标签:定义 ext div start 专用 clear 错误提示 回车 inpu 题目描述: 汇编语言之加法练习程序 标签:定义 ext div start 专用 clear 错误提示 回车 inpu 原文地址:https://www.cnblogs.com/xwh-blogs/p/12716861.html 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
上一篇:js数组方法整理