需要设计一个程序 内容含有加法即可
如何最简单的设计出一个程序呢
enterline macro ;定义回车换行的宏指令
mov dl,13
mov ah,2
int 21h
mov dl,10
mov ah,2
int 21h
endm
DATAS SEGMENT
;此处输入数据段代码
info db'Please enter an addition expression, such as A + B$'
err db 'Illegal input! Please Try Again$'
again db'Invalid input, try again.$'
overout db'The number overflowed, try again$'
overout1 db'The result overflowed, try again$'
inn db'Please enter your answer$'
win db'Congratulations, the answer is right$'
note db'Note: press the r key to continue to input the next question, and press the q key to exit the program$'
lose1 db'Sorry, your answer is wrong. You have 2 more chances$'
lose2 db'Sorry, your answer is wrong. You have 1 more chances$'
lose3 db'Sorry, your answer is wrong. The right answer is $'
result dw 0 ;用于存放最终结果
errtime db ? ;答案错误次数
flag db ?
buf db 30,?,30 dup(0) ;定义键盘接收字符缓冲区,最多接收19个字符
ff db ? ;输出的判断前导0的标志
input db ? ;储存输入的按键
op1 dw ? ;定义两个操作数
op2 dw ?
DATAS ENDS
STACKS SEGMENT
;此处输入堆栈段代码
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
;此处输入代码段代码
main: ;加法模块 ;设计完加法子程序后把下面这部分也封装进去
lea dx,info ;提示信息
mov ah,9
int 21h
enterline
mov errtime,3 ;允许犯错的次数
call inputi ;调用输入的子程序,输入公式
cmp flag,1
je main ;由于错误输入跳回a1重新进行加法操作
cmp flag,2
je main ;由于溢出跳回a1重新输入
shuru:
lea dx,inn ;提示输入信息
mov ah,9
int 21h
enterline
call input2 ;调用输入的子程序,输入答案
cmp flag,1
je shuru ;由于错误输入跳回shuru
cmp flag,2
je shuru ;由于错误输入跳回shuru
mov bx,result ;判断输入的答案是否正确
cmp bx,op1
je correct
dec errtime ;尝试次数减1
cmp errtime,2 ;剩余两次机会
je error1
cmp errtime,1 ;剩余1次机会
je error2
cmp errtime,0 ;不剩机会
je error3
error1:
lea dx,lose1 ;提示信息
mov ah,9
int 21h
enterline
jmp shuru ;执行完后跳回主菜单
error2:
lea dx,lose2 ;提示信息
mov ah,9
int 21h
enterline
jmp shuru ;执行完后跳回主菜单
error3:
lea dx,lose3 ;提示信息
mov ah,9
int 21h
mov bx,result ;result是正确的和
call outi ;输出正确结果,结束此题
enterline
judge1: ;结果错误时的按键提示
lea dx,note ;提示信息
mov ah,9
int 21h
enterline
call judge ;判断输入的键是什么键
enterline
cmp input,'r'
je main
cmp input,'q'
je stop
jmp judge1
correct: ;表示结果正确
lea dx,win ;提示信息
mov ah,9
int 21h
enterline
judge2: ;结果正确时的按键提示
lea dx,note ;提示信息
mov ah,9
int 21h
enterline
call judge ;判断输入的键是什么键
enterline
cmp input,'r'
je main
cmp input,'q'
je stop
jmp judge2
stop:
MOV AH,4CH
INT 21H
inputi proc ;输入子程序如下;专门用于存表达式的子程序
mov flag,0 ;初始化flag,用于标志错误或溢出
mov result,0 ;存放累加结果
lea dx,buf ;从键盘接收输入数值放入buf缓冲区(输入操作)
mov ah,10
int 21h
enterline ;回车换行
mov cl,buf+1 ;获取实际键入字符数,置于CX寄存器中
xor ch,ch ;ch清0
xor di,di ;累加器清0
xor dx,dx ;dX寄存器清0
mov bx,1 ;由于从个位数开始算起,因而将所乘权值设为1
lea si,buf+2 ;将si指向接收到的第1个字符位置
add si,cx ;因为从个位算起,所以将si指向最后1个接收到的个位数
dec si ;往回减1使其指向字串最后一个元素
;cov是检测并生成第一个数字的步骤
cov:mov al,[si] ;取出个位数给al
cmp al,'+'
jz addi ;遇见空格则跳转
cmp al,'0' ;边界检查:如果输入不是0-9的数字,就报错
jb wrong
cmp al,'9'
ja wrong
sub al,30h ;将al中的ascii码转为数字
xor ah,ah
mul bx ;乘以所处数位的权值
cmp dx,0 ;判断结果是否超出16位数范围,如超出则报错
jne yichu
add di,ax ;将形成的数值叠加放在累加器di中
cmp di,99
ja yichu ;超过100报错
mov ax,bx ;将BX中的数位权值扩大10倍,此处需要借助ax来实现
mov bx,10
mul bx
mov bx,ax
dec si ;si指针减1,指向前一数位
loop cov ;按CX中的字符个数计数循环
lastadd: ;从后往前数的最后一个加数,执行lastadd时loop已经结束
mov bx,result
add bx,di ;存在bx寄存器中带回
mov result,bx ;备份结果在result中
jmp return
addi:
mov bx,result ;把当前累加值赋给bx
add bx,di ;di表示当前某一个加数
cmp bx,result ;判断是否溢出超过65535
jb yichu
mov result,bx ;将结果存回result
xor ax,ax
xor bx,bx
xor di,di ;累加器清0
mov bx,1 ;由于下一个加数又从个位数开始算起,因而将所乘权值设为1
dec si ;向前移动一格位置
dec cx ;遇到加号cx相应的减少1
jmp cov ;结束后跳到cov部分
wrong: ;输入错误
lea dx,err
mov ah,9
int 21h
mov flag,1
enterline
jmp return
yichu: ;加数超过100
mov flag,2
lea dx,overout
mov ah,9
int 21h
enterline
return:
ret
inputi endp
input2 proc ;专用于输入纯数字答案的子程序
mov flag,0
lea dx,buf ;从键盘接收输入数值放入buf缓冲区
mov ah,10
int 21h
enterline ;回车换行
mov cl,buf+1 ;获取实际键入字符数,置于CX寄存器中
xor ch,ch
xor di,di ;累加器清0
xor dx,dx ;DX寄存器清0
mov bx,1 ;由于从个位数开始算起,因而将所乘权值设为1
lea si,buf+2 ;将si指向接收到的第1个字符位置
add si,cx ;因为从个位算起,所以将si指向最后1个接收到的个位数
dec si
cov:mov al,[si] ;取出个位数给al
cmp al,'0' ;边界检查:如果输入不是0-9的数字,就报错
jb wrong2
cmp al,'9'
ja wrong2
sub al,30h ;将al中的ascii码转为数字
xor ah,ah
mul bx ;乘以所处数位的权值
cmp dx,0 ;判断结果是否超出16位数范围,如超出则报错
jne over2
add di,ax ;将形成的数值放在累加器di中
jc over2 ;如数值超过16位数范围报错
mov ax,bx ;将BX中的数位权值乘以10
mov bx,10
mul bx
mov bx,ax
dec si ;si指针减1,指向前一数位
loop cov ;按CX中的字符个数计数循环
mov op1,di ;将结果储存在op1中
jmp return2
wrong2: ;给出错误提示
lea dx,err
mov ah,9
int 21h
enterline
mov flag,1
jmp return2
over2:
lea dx,overout
mov ah,9
int 21h
enterline
mov flag,2
return2:
ret
input2 endp
outi proc ;输出子程序
mov ax,bx ;待输出的数先存在bx里面,在给ax
mov bx,10000 ;初始数位权值为10000
mov ff,0 ;每次都赋初值0
cov1:xor dx,dx ;将dx:ax中的数值除以权值
div bx
mov cx,dx ;余数备份到CX寄存器中
cmp ff,0 ;检测是否曾遇到非0商值
jne nor1 ;如遇到过,则不管商是否为0都输出显示
cmp ax,0 ;如未遇到过,则检测商是否为0
je cont ;为0则不输出显示
nor1:
mov dl,al ;将商转换为ascii码输出显示
add dl,30h
mov ah,2
int 21h
mov ff,1 ;曾遇到非0商,则将标志置1
cont:
cmp bx,10 ;检测权值是否已经修改到十位了
je outer ;如果相等,则完成最后的个位数输出显示
xor dx,dx ;将数位权值除以10
mov ax,bx
mov bx,10
div bx
mov bx,ax
mov ax,cx ;将备份的余数送入AX
jmp cov1 ;继续循环
outer:
mov dl,cl ;最后的个位数变为ascii码输出显示
add dl,30h
mov ah,2
int 21h
enterline
ret
outi endp
judge proc
mov ah,1
int 21h
mov input,al ;将储存的字符给input
ret
judge endp
CODES ENDS
END START