主题:帮忙找茬:一个有符号四则运算计算器程序
要求程序能接收键入的算式,在接收到‘=’号时,计算并以有符号十进制数的形式显示结果,然后允许用户继续键入算式。如果键入算式后再键入‘.’,则显示结果并结束整个程序。(‘/’为整除)
DATA SEGMENT
MSG_INTRO DB "Input the Expression(Operand MAX:255,End with=):",0AH,0DH,"$"
MSG_INVALID DB "Invalid Expression.",0AH,0DH,"$"
MSG_RESULT DB "Result:","$"
MSG_NEWLINE DB 0AH,0DH,"$"
BUFFER DB 10H DUP(?) ;BUFFER 用于保存表达式。
NUMBER_FLAG DB 00H ;NUMBER_FLAG 用于标记操作数是否为负数。
MINUS EQU 2DH
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
start: ;初始化。
MOV AX,DATA
MOV DS,AX
LEA BX,BUFFER
MOV CX,00H ;提示输入信息。
MOV DX,OFFSET MSG_INTRO
MOV AH,09H
INT 21H
GET_EXPRESSION: ;获取用户输入的需要计算的表达式字符串。
MOV AH,01H
INT 21H
;CMP AL,0DH ;输入表达式以回车结束。
;JE INPUT_FINISH
MOV [BX],AL
INC BX
INC CX
JMP GET_EXPRESSION
; INPUT_FINISH:
; MOV DX,OFFSET MSG_NEWLINE
; MOV AH,09H
; INT 21H;准备开始计算。
SUB BX,CX
MOV CX,00H;如果表达式的第一个字符为负号,第一个操作数为负数。
CMP BUFFER[BX],MINUS
JNE GET_NUMBER_1
INC BX
INC NUMBER_FLAG
GET_NUMBER_1:;获得第一个操作数。
MOV DX,[BX]
SUB DX,30H
ADC CX,DX
INC BX;如果下一个字符是加减乘除四则运算符之一,则跳转。
MOV DL,[BX]
CMP DL,30H
JL GET_NEXT_NUMBER
MOV AX,CX
MOV DL,10D
IMUL DL
MOV CX,AX
JMP GET_NUMBER_1
GET_NEXT_NUMBER:
;先获得第二个操作数,并保存运算符在SI寄存器。
; 如果NUMBER_FLAG标志为1,则操作数一为负数,高字保存在DX,低字保存在AX。
CMP NUMBER_FLAG,0
JE SAVE_NUMBER1
DEC NUMBER_FLAG ; NUMBER_FLAG标志消零。
MOV AX,CX
MOV DL,-1H
IMUL DL
MOV CX,AX
SAVE_NUMBER1: ;保存第一个操作数至SI寄存器。
MOV DL,CL
MOV DH,00H
MOV SI,DX ;保存运算符至DH寄存器。
MOV DH,[BX]
INC BX
MOV CX,00H ;如果表达式中运算符后面的字符为负号,第二个操作数为负数。
CMP BUFFER[BX],MINUS
JNE GET_NUMBER_2
INC BX
INC NUMBER_FLAG
GET_NUMBER_2: ;获得第二个操作数。
MOV DL,[BX]
MOV DL,30H
ADC CL,DL ;如果下一个字符是"等于"符号,则跳转至计算。
CMP BUFFER[BX+1],"="
JE PRE_ACCOUNT
INC BX
MOV AX,CX
MOV DL,10D
IMUL DL
MOV CX,AX
JMP GET_NUMBER_2
PRE_ACCOUNT: ;如果NUMBER_FLAG标志为1,则操作数二为负数。
CMP NUMBER_FLAG,0
JE ACCOUNT
MOV AX,CX
MOV DL,-1H
IMUL DL
MOV CX,AX
ACCOUNT:
MOV BH,DH
MOV DX,OFFSET MSG_RESULT
MOV AH,09H
INT 21H ;开始计算表达式。
CMP BH,"+"
JE OPTR_ADD
CMP BH,"-"
JE OPTR_SUB
CMP BH,"*"
JE OPTR_MUL
CMP BH,"/"
JE OPTR_DIV
JMP QUIT ;输出计算结果。
OPTR_ADD:
MOV BX,SI
ADC BL,CL
MOV BH,00H
MOV SI,BX
CALL BINIDEC
JMP SHOW_RESULT
OPTR_SUB:
MOV BX,SI
SUB BX,CX
MOV SI,BX
CALL BINIDEC
JMP SHOW_RESULT
OPTR_MUL:
MOV AX,CX
IMUL SI
MOV SI,AX
CALL BINIDEC
JMP SHOW_RESULT
OPTR_DIV:
MOV BX,SI
MOV AL,BL
DIV CL
MOV BH,00H
MOV BL,AL
MOV SI,BX
CALL BINIDEC
;JMP SHOW_RESULT
;SHOW_RESULT: ;将计算结果转化为十进制数字并显示在屏幕上。
:QUIT:
;MOV AH,4CH;Return to DOS.
;INT 21H
BINIDEC PROC NEAR
MOV CX,100D
CALL DEC_DIV
MOV CX,10D
CALL DEC_DIV
MOV CX,1D
CALL DEC_DIV
RET
BINIDEC ENDP
DEC_DIV PROC NEAR
MOV AX,SI
MOV DX,0
DIV CX
MOV SI,DX
MOV DL,AL
ADD DL,30H
MOV AH,2H
INT 21H
RET
DEC_DIV ENDP
CODE ENDS
END START
上面的程序link后没问题,就是实现不了四则计算结果输出,恳请大家帮帮忙!
还有上面代码中的
INC BX;如果下一个字符是加减乘除四则运算符之一,则跳转。
MOV DL,[BX]
CMP DL,30H
cmp dl,30这个比较干嘛用
DATA SEGMENT
MSG_INTRO DB "Input the Expression(Operand MAX:255,End with=):",0AH,0DH,"$"
MSG_INVALID DB "Invalid Expression.",0AH,0DH,"$"
MSG_RESULT DB "Result:","$"
MSG_NEWLINE DB 0AH,0DH,"$"
BUFFER DB 10H DUP(?) ;BUFFER 用于保存表达式。
NUMBER_FLAG DB 00H ;NUMBER_FLAG 用于标记操作数是否为负数。
MINUS EQU 2DH
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
start: ;初始化。
MOV AX,DATA
MOV DS,AX
LEA BX,BUFFER
MOV CX,00H ;提示输入信息。
MOV DX,OFFSET MSG_INTRO
MOV AH,09H
INT 21H
GET_EXPRESSION: ;获取用户输入的需要计算的表达式字符串。
MOV AH,01H
INT 21H
;CMP AL,0DH ;输入表达式以回车结束。
;JE INPUT_FINISH
MOV [BX],AL
INC BX
INC CX
JMP GET_EXPRESSION
; INPUT_FINISH:
; MOV DX,OFFSET MSG_NEWLINE
; MOV AH,09H
; INT 21H;准备开始计算。
SUB BX,CX
MOV CX,00H;如果表达式的第一个字符为负号,第一个操作数为负数。
CMP BUFFER[BX],MINUS
JNE GET_NUMBER_1
INC BX
INC NUMBER_FLAG
GET_NUMBER_1:;获得第一个操作数。
MOV DX,[BX]
SUB DX,30H
ADC CX,DX
INC BX;如果下一个字符是加减乘除四则运算符之一,则跳转。
MOV DL,[BX]
CMP DL,30H
JL GET_NEXT_NUMBER
MOV AX,CX
MOV DL,10D
IMUL DL
MOV CX,AX
JMP GET_NUMBER_1
GET_NEXT_NUMBER:
;先获得第二个操作数,并保存运算符在SI寄存器。
; 如果NUMBER_FLAG标志为1,则操作数一为负数,高字保存在DX,低字保存在AX。
CMP NUMBER_FLAG,0
JE SAVE_NUMBER1
DEC NUMBER_FLAG ; NUMBER_FLAG标志消零。
MOV AX,CX
MOV DL,-1H
IMUL DL
MOV CX,AX
SAVE_NUMBER1: ;保存第一个操作数至SI寄存器。
MOV DL,CL
MOV DH,00H
MOV SI,DX ;保存运算符至DH寄存器。
MOV DH,[BX]
INC BX
MOV CX,00H ;如果表达式中运算符后面的字符为负号,第二个操作数为负数。
CMP BUFFER[BX],MINUS
JNE GET_NUMBER_2
INC BX
INC NUMBER_FLAG
GET_NUMBER_2: ;获得第二个操作数。
MOV DL,[BX]
MOV DL,30H
ADC CL,DL ;如果下一个字符是"等于"符号,则跳转至计算。
CMP BUFFER[BX+1],"="
JE PRE_ACCOUNT
INC BX
MOV AX,CX
MOV DL,10D
IMUL DL
MOV CX,AX
JMP GET_NUMBER_2
PRE_ACCOUNT: ;如果NUMBER_FLAG标志为1,则操作数二为负数。
CMP NUMBER_FLAG,0
JE ACCOUNT
MOV AX,CX
MOV DL,-1H
IMUL DL
MOV CX,AX
ACCOUNT:
MOV BH,DH
MOV DX,OFFSET MSG_RESULT
MOV AH,09H
INT 21H ;开始计算表达式。
CMP BH,"+"
JE OPTR_ADD
CMP BH,"-"
JE OPTR_SUB
CMP BH,"*"
JE OPTR_MUL
CMP BH,"/"
JE OPTR_DIV
JMP QUIT ;输出计算结果。
OPTR_ADD:
MOV BX,SI
ADC BL,CL
MOV BH,00H
MOV SI,BX
CALL BINIDEC
JMP SHOW_RESULT
OPTR_SUB:
MOV BX,SI
SUB BX,CX
MOV SI,BX
CALL BINIDEC
JMP SHOW_RESULT
OPTR_MUL:
MOV AX,CX
IMUL SI
MOV SI,AX
CALL BINIDEC
JMP SHOW_RESULT
OPTR_DIV:
MOV BX,SI
MOV AL,BL
DIV CL
MOV BH,00H
MOV BL,AL
MOV SI,BX
CALL BINIDEC
;JMP SHOW_RESULT
;SHOW_RESULT: ;将计算结果转化为十进制数字并显示在屏幕上。
:QUIT:
;MOV AH,4CH;Return to DOS.
;INT 21H
BINIDEC PROC NEAR
MOV CX,100D
CALL DEC_DIV
MOV CX,10D
CALL DEC_DIV
MOV CX,1D
CALL DEC_DIV
RET
BINIDEC ENDP
DEC_DIV PROC NEAR
MOV AX,SI
MOV DX,0
DIV CX
MOV SI,DX
MOV DL,AL
ADD DL,30H
MOV AH,2H
INT 21H
RET
DEC_DIV ENDP
CODE ENDS
END START
上面的程序link后没问题,就是实现不了四则计算结果输出,恳请大家帮帮忙!
还有上面代码中的
INC BX;如果下一个字符是加减乘除四则运算符之一,则跳转。
MOV DL,[BX]
CMP DL,30H
cmp dl,30这个比较干嘛用