題目描述:
加法練習程序。要求:從鍵盤輸入百位數以內的加法算式,並提示輸入答案,若正確給出正確提示,若錯誤給出錯誤提示,並提示輸入答案;按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