• 汇编语言之加法练习程序


    题目描述:

      加法练习程序。要求:从键盘输入百位数以内的加法算式,并提示输入答案,若正确给出正确提示,若错误给出错误提示,并提示输入答案;按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
  • 相关阅读:
    安卓基础值之Intent
    输入值/表单提交参数过滤有效防止sql注入的方法
    一致性hash
    linux授权某个用户对某个目录有读写的权限
    mysql分区功能详细介绍,以及实例
    SVN分支与主干
    solr查询
    mysql-proxy做客户端连接转发【外网访问内网mysql】
    liunx 下安装 php_screw 扩展 以及报错处理
    邮件发送
  • 原文地址:https://www.cnblogs.com/xwh-blogs/p/12716861.html
Copyright © 2020-2023  润新知