;本程序实现加减混合运算输入格式必须为1+2-3=
;程序思路:遇到一个操作符执行前一次运算,等号执行最后一次运算,然后保存本次操作符
;---------提示信息------
DISPL MACRO DI
MOV AH,9
MOV DX,DI
INT 21H
ENDM
;-----------
DISP MACRO V AR
MOV AH,2
MOV DL,V AR
INT 21H
ENDM
;--------输入函数-------
INPUT MACRO
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV BX,0 ;BX存放十进制数
CLC
MOV DX,0
NEXT0:
MOV AH,1
INT 21H
CMP AL,2BH ;判断输入是否为'+'
JE NEXT2
CMP AL,2DH ;判断输入是否为'-'
JE NEXT2
CMP AL,3DH ;判断‘=’
JE NEXT2
SUB AL,30H
JL NEXT1
CMP AL,9
JG NEXT1
MOV AH,0 ;将输入的数转换成10进制数
XCHG AX,BX
MOV CX,10
MUL CX
ADD AX,BX
JC NEXT1
XCHG AX,BX
JMP NEXT0
NEXT1:
MOV DX,0
MOV BX,0
MOV DI,OFFSET STR ;提示出错
DISPL DI
MOV DI,OFFSET STR2
DISPL DI
JMP NEXT0
NEXT2:
CMP DX,0
JNZ NEXT1
CMP COUNT,1 ;第一次输入存到buf0以后输入全部存放到buf1 JE L0
MOV BUF0,BX
JMP L1
L0: MOV BUF1,BX
JMP NEXT3
L1: MOV OPER,AL ;将操作符保存至oper
MOV COUNT,1
MOV BX,0
JMP NEXT0
NEXT3:
CMP OPER,'+';判读那是何种操作
JE N0
CMP OPER,'-'
JE N1
N0:
MOV BX,BUF0 ;加法相应操作
ADD BX,BUF1
MOV BUF0,BX
CMP AL,'='
JE NEXT4
JMP L1
N1:
MOV DX,BUF0 ;加法操作
CMP FLAG,1 ;如果原来buf0里的数是负数用buf1-buf0的绝对值
JNE N2
XCHG DX,BUF1
MOV FLAG,0
N2: CLC
SBB DX,BUF1
JNC N3
MOV FLAG,1
NEG DX ;如果相减为负数则存放绝对值N3:
MOV BUF0,DX
CMP AL,'='
JE NEXT4
JMP L1
NEXT4:
CMP FLAG,1
JNE NEXT5
DISP '-';若果结果为负数输出负号
NEXT5:
CALL PRINT
POP DX
POP CX
POP BX
POP AX
ENDM
DATAS SEGMENT
STR DB0AH,0DH,'$'
STR0 DB'please input arithmetic expressions:',0AH,0DH,'$' STR2 DB'the num is unexpected,input again:',0AH,0DH,'$' BUF0 DW?
BUF1 DW?
FLAG DB 0
OPER DB?
COUNT D B 0
DATAS ENDS
STACKS SEGMENT
DW256 DUP(?) ;此处输入堆栈段代码
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
MOV DI,OFFSET STR0
DISPL DI
INPUT
MOV AH,4CH
INT 21H
;-----------显示函数--------
PRINT PROC NEAR
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV CX,0 ;记录有效数字位数MOV BX,10 ;除10取余
MOV AX,BUF0
LAST:
MOV DX,0
DIV BX
PUSH DX
INC CX
CMP AX,0
JNZ LAST
AGE:
POP DX ;出栈输出
OR DX,30H
MOV AH,2
INT 21H
LOOP AGE
POP DX
POP CX
POP BX
POP AX
RET
PRINT ENDP
CODES ENDS
END START
DISP MACRO V AR
MOV AH,2
MOV DL,V AR
INT 21H
ENDM
DATAS SEGMENT
DATA0 DB'PLEASE INPUT A NUMBER(0-999):','$'
DATA1 DB' over flow input again:','$'
DATA2 DB'PLEASE INPUT ANOTHER NUMBER(EXP:123)','$' DATA3 DB'PLEASE INPUT AN OPREATOR:','$'
DATA4 DB'THE OPERATOR IS WRONG,INPUT AGAIN:','$' OPER DB?
FLAG DB 0
FLAG1 DB 0
DATA DW 3 DUP(?)
DATAS ENDS
STACKS SEGMENT
DW 256 DUP(?)
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
MOV DI,OFFSET DATA0 ;提示信息
CALL DISPL
MOV SI,0 ;SI作为数组下标
CALL INPUT
CALL NEWLINE
MOV DI,OFFSET DATA3 ;提示信息
CALL DISPL
AGAIN:
MOV AH,1 ;1号功能输入四则运算符
INT 21H
CMP AL,'+';判断输入的是不是+,-,*,/ JE NEXT0
CMP AL,'-'
JE NEXT0
CMP AL,'*'
JE NEXT0
CMP AL,'/'
JE NEXT0
CALL NEWLINE ;输入的运算符不合法,重新输入MOV DI, OFFSET DATA4
CALL DISPL
JMP AGAIN
NEXT0:
MOV OPER,AL ;保存运算符
CALL NEWLINE
MOV DI,OFFSET DATA2 ;输入第二个操作数
MOV SI,2
CALL INPUT
MOV AX,DATA[0]
MOV BX,DATA[2]
CMP OPER,'+';判断是那种操作,进行运算JE NEXT1
CMP OPER,'-'
JE NEXT2
CMP OPER,'*'
JE NEXT3
CMP OPER,'/'
JE NEXT4
NEXT1: ;加法运算
CLC
ADC AX,BX
JNC N1
MOV FLAG,1 ;判断是否进位
N1: MOV DATA[4],AX ;运算结果放入内存JMP OUTPUT
NEXT2: ;减法运算
CLC
SBB AX,BX
JNC N2
MOV FLAG,1 ;判断是否借位
NEG AX
N2: MOV DATA[4],AX ;运算结果放入内存JMP OUTPUT
NEXT3: ;乘法运算
CLC
MOV DX,0
MUL BX
MOV DATA[4],AX ;运算结果放入内存
JMP OUTPUT
NEXT4: ;除法运算
CLC
MOV DX,0
CMP BX,0
JNZ N4 ;判断除数是否为0
CALL NEWLINE
CALL ERROR
CALL NEWLINE
MOV DI,OFFSET DATA2
MOV SI,2
CALL INPUT
JMP NEXT4
N4: DIV BX
MOV DATA[4],AX ;运算结果放入内存OUTPUT:
CALL NEWLINE
MOV DI,0 ;输出第一个操作数
CALL PRINT
DISP OPER ;输出运算符
MOV DI,2
CALL PRINT ;输出第二个操作数
DISP '='
CMP FLAG,1
JNZ N EXT5
DISP '-'
NEXT5:
MOV DI,4
CALL PRINT ;输出结果
MOV AH,4CH
INT 21H
;-----------输入函数------------
INPUT PROC NEAR
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV BX,0 ;BX存放十进制数
CLC
MOV DX,0
L0:
;----------输入数字----------
MOV AH,1 ;判断数字是否合法INT 21H
CMP AL,0DH
JE L2
SUB AL,30H
JL L1
JG L1
;---------转换成十进制数-------
MOV AH,0 ;转换成10进制数放入内存XCHG AX,BX
MOV CX,10
MUL CX
ADD AX,BX
JC L1
XCHG AX,BX
JMP L0
L1:
MOV DX,0
MOV BX,0
CALL NEWLINE
CALL ERROR
JMP L0
L2:
CMP DX,0
JNZ L1
MOV DATA[SI],BX
MOV DX,0
POP DX
POP CX
POP BX
POP AX
RET
INPUT ENDP
;--------------提示信息------------
DISPL PROC NEAR
MOV AH,9
MOV DX,DI
INT 21H
RET
DISPL ENDP
;-------回车换行--------
NEWLINE PROC NEAR
PUSH AX
PUSH DX
MOV DL,0AH
INT 21H
MOV DL,0DH
MOV AH,2
INT 21H
POP DX
POP AX
RET
NEWLINE ENDP
;----------错误提示---------------- ERROR PROC NEAR
PUSH AX
PUSH DX
MOV DX,OFFSET DATA1
MOV AH,9
INT 21H
POP DX
POP AX
RET
ERROR ENDP
;-----------显示函数--------
PRINT PROC NEAR
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV CX,0
MOV BX,10
MOV AX,DATA[DI]
LAST:
MOV DX,0 ;除10压栈
DIV BX
PUSH DX
INC CX
CMP AX,0
JNZ LAST
AGE:
POP DX ;出栈输出
OR DX,30H
MOV AH,2
INT 21H
LOOP AGE
POP DX
POP CX
POP BX
POP AX
RET
PRINT ENDP CODES ENDS
END START