assume cs:code,ds:data
data segment
Numeric STRUC
Integer DW 0,0,0
Signed DW 0
Numeric ENDS
num_1 Numeric <>
num_2 Numeric <>
num_3 Numeric <>
buffer DB 8 dup(0)
msg1 db 'Input a number[-65535,65535]:',36
msg2 db 'Please input a rightful number!',0ah,0dh,36
msg3 db 'The number is too big!',0ah,0dh,36
msg4 db 'divider can not be zero!',0ah,0dh,36
data ends
code segment
_Break MACRO
NOP
INT 1H
NOP
ENDM
_EnterLine MACRO
MOV AH,02
MOV DL,0AH
INT 21H
MOV DL,0DH
INT 21H
ENDM
_PushAll MACRO
PUSH SI
PUSH DI
PUSH BX
PUSH CX
PUSH DX
ENDM
_PopAll MACRO
POP DX
POP CX
POP BX
POP DI
POP SI
ENDM
_start:
MOV AX,DATA
MOV DS,AX
MOV ES,AX
PUSH OFFSET num_1
CALL _GetNumeric
PUSH OFFSET num_2
CALL _GetNumeric
CALL _CopyNumeric
PUSH OFFSET num_2
PUSH OFFSET num_3
CALL _AddNumeric
CALL _CopyNumeric
PUSH OFFSET num_2
PUSH OFFSET num_3
CALL _SubNumeric
CALL _CopyNumeric
PUSH OFFSET num_2
PUSH OFFSET num_3
CALL _MulNumeric
CALL _CopyNumeric
PUSH OFFSET num_2
PUSH OFFSET num_3
CALL _DivNumeric
MOV AX,4C00H
INT 21H
_AddNumeric PROC
PUSH BP
MOV BP,SP
_PushAll
PUSH [BP+4]
PUSH 0
CALL _OutputNumeric
MOV AH,2
MOV DL,'+'
INT 21H
PUSH [BP+6]
PUSH 0
CALL _OutputNumeric
MOV AH,2
MOV DL,'='
INT 21H
MOV SI,[BP+4]
MOV DI,[BP+6]
PUSH [DI]
PUSH [SI]
MOV AX,[SI].Signed
SUB AX,[DI].Signed
TEST AX,AX
JE _AnSameSigned
CALL _SimpleSub
MOV [SI],AX
MOV AX,[SI].Signed
XOR AX,DX
MOV [SI].Signed,AX
JMP _AnEnd
_AnSameSigned:
CALL _SimpleAdd
MOV [SI],AX
MOV [SI+2],DX
_AnEnd:
PUSH [BP+4]
PUSH 0
CALL _OutputNumeric
_EnterLine
_PopAll
MOV SP,BP
POP BP
RET 4
_AddNumeric ENDP
_SubNumeric PROC
PUSH BP
MOV BP,SP
_PushAll
PUSH [BP+4]
PUSH 0
CALL _OutputNumeric
MOV AH,2
MOV DL,'-'
INT 21H
PUSH [BP+6]
PUSH 0
CALL _OutputNumeric
MOV AH,2
MOV DL,'='
INT 21H
MOV SI,[BP+4]
MOV DI,[BP+6]
PUSH [DI]
PUSH [SI]
MOV AX,[SI].Signed
SUB AX,[DI].Signed
TEST AX,AX
JNE _SnSameSigned
CALL _SimpleSub
MOV [SI],AX
MOV AX,[SI].Signed
XOR AX,DX
MOV [SI].Signed,AX
JMP _SnEnd
_SnSameSigned:
CALL _SimpleAdd
MOV [SI],AX
MOV [SI+2],DX
_SnEnd:
PUSH [BP+4]
PUSH 0
CALL _OutputNumeric
_EnterLine
_PopAll
MOV SP,BP
POP BP
RET 4
_SubNumeric ENDP
_MulNumeric PROC
PUSH BP
MOV BP,SP
SUB SP,20
PUSH DS
PUSH ES
_PushAll
PUSH [BP+4]
PUSH 0
CALL _OutputNumeric
MOV AH,2
MOV DL,'*'
INT 21H
PUSH [BP+6]
PUSH 0
CALL _OutputNumeric
MOV AH,2
MOV DL,'='
INT 21H
MOV WORD PTR [BP-2],0
MOV WORD PTR [BP-4],10000
MOV SI,[BP+4]
MOV DI,[BP+6]
MOV AX,[SI].Signed
XOR AX,[DI].Signed
MOV [SI].Signed,AX
MOV AX,[SI]
MOV DX,[SI+2]
MOV BX,10000
DIV BX
MOV [SI],DX
MOV [SI+2],AX
MOV AX,[DI]
MOV DX,[DI+2]
DIV BX
MOV [BP-20],DX
MOV [BP-18],AX
MOV AX,[SI]
MUL WORD PTR [BP-20]
DIV WORD PTR [BP-4]
MOV [BP-16],DX
MOV [BP-2],AX
MOV AX,[SI+2]
MUL WORD PTR [BP-20]
ADD AX,[BP-2]
ADC DX,0
DIV WORD PTR [BP-4]
MOV [BP-14],DX
MOV [BP-12],AX
MOV AX,[SI]
MUL WORD PTR [BP-18]
DIV WORD PTR [BP-4]
MOV [BP-10],DX
MOV [BP-2],AX
MOV AX,[SI+2]
MUL WORD PTR [BP-18]
ADD AX,[BP-2]
ADC DX,0
DIV WORD PTR [BP-4]
MOV [BP-8],DX
MOV [BP-6],AX
MOV AX,[BP-16]
MOV [SI],AX
XOR DX,DX
XOR BX,BX
MOV AX,[BP-14]
ADD AX,[BP-10]
ADC BX,0
DIV WORD PTR [BP-4]
MOV [SI+2],DX
ADD BX,AX
MOV AX,[BP-12]
ADD AX,BX
ADD AX,[BP-8]
MOV [SI+4],AX
PUSH SI
PUSH 1
CALL _OutputNumeric
_EnterLine
_PopAll
POP ES
POP DS
ADD SP,20
MOV SP,BP
POP BP
RET 4
_MulNumeric ENDP
_DivNumeric PROC
PUSH BP
MOV BP,SP
_PushAll
PUSH [BP+4]
PUSH 0
CALL _OutputNumeric
MOV AH,2
MOV DL,'/'
INT 21H
PUSH [BP+6]
PUSH 0
CALL _OutputNumeric
MOV AH,2
MOV DL,'='
INT 21H
MOV SI,[BP+4]
MOV DI,[BP+6]
MOV BX,[DI]
TEST BX,BX
JNE _DividerIsNotZero
MOV AH,9
LEA DX,msg4
INT 21H
JMP _DivEnd
_DividerIsNotZero:
MOV AX,[SI].Signed
XOR AX,[DI].Signed
MOV [SI].Signed,AX
MOV AX,[SI]
XOR DX,DX
DIV BX
MOV [SI],AX
PUSH [BP+4]
PUSH 0
CALL _OutputNumeric
_DivEnd:
_EnterLine
_PopAll
MOV SP,BP
POP BP
RET 4
_DivNumeric ENDP
_SimpleAdd PROC
PUSH BP
MOV BP,SP
XOR DX,DX
MOV AX,[BP+4]
ADD AX,[BP+6]
ADC DX,0
MOV SP,BP
POP BP
RET 4
_SimpleAdd ENDP
_SimpleSub PROC
PUSH BP
MOV BP,SP
SUB SP,2
MOV WORD PTR [BP-2],0
MOV AX,[BP+4]
MOV DX,[BP+6]
CMP AX,DX
JAE _@15
XCHG AX,DX
INC WORD PTR [BP-2]
_@15:
SUB AX,DX
MOV DX,WORD PTR [BP-2]
ADD SP,2
MOV SP,BP
POP BP
RET 4
_SimpleSub ENDP
_GetNumeric PROC
PUSH BP
MOV BP,SP
SUB SP,6
_PushAll
JMP _GNBegin
_Number2Big:
MOV AH,09H
LEA DX,msg3
INT 21H
_GNBegin:
CALL _InputNumber
MOV [BP-2],AX
MOV WORD PTR [BP-4],0
MOV WORD PTR [BP-6],10
LEA SI,buffer
_GNLoop:
XOR AX,AX
LODSB
TEST AL,AL
JE _GNEnd
SUB AL,030H
MOV BX,AX
MOV AX,[BP-4]
MUL WORD PTR [BP-6]
JC _Number2Big
ADD AX,BX
JC _Number2Big
MOV [BP-4],AX
JMP _GNLoop
_GNEnd:
MOV SI,[BP+4]
PUSH [BP-4]
POP [SI].Integer
PUSH [BP-2]
POP [SI].Signed
_PopAll
ADD SP,6
MOV SP,BP
POP BP
RET 2
_GetNumeric ENDP
_InputNumber PROC
JMP _@10
_@9:
MOV AH,09
LEA DX,msg2
INT 21H
_@10:
MOV AH,09
LEA DX,msg1
INT 21H
XOR AX,AX
MOV CX,4
LEA DI,buffer
PUSH DI
REP STOSW
POP DI
XOR CX,CX
XOR BX,BX
MOV AH,01
INT 21H
CMP AL,'-'
JNE _@11
INC BX
JMP _@12
_@11:
CMP AL,'+'
JNE _@13
_@12:
MOV AH,01H
INT 21H
_@13:
CMP AL,0DH
JE _@14
CMP AL,'0'
JL _@9
CMP AL,'9'
JG _@9
STOSB
INC CX
CMP CX,5
JGE _@14
JMP _@12
_@14:
_EnterLine
MOV AX,BX
RET
_InputNumber ENDP
_OutputNumber PROC
PUSH BP
MOV BP,SP
SUB SP,4
_PushAll
MOV WORD PTR [BP-2],0
MOV WORD PTR [BP-4],1000
MOV CX,4
MOV AX,[BP+6]
_@1:
XOR DX,DX
DIV WORD PTR [BP-4]
XCHG AX,DX
TEST DX,DX
JNE _@2
MOV BX,[BP+4]
ADD BX,[BP-2]
TEST BX,BX
JE _@3
_@2:
PUSH AX
MOV AH,02
ADD DL,030H
INT 21H
POP AX
INC WORD PTR [BP-2]
_@3:
PUSH AX
XOR DX,DX
MOV AX,[BP-4]
MOV BX,10
DIV BX
MOV [BP-4],AX
POP AX
LOOP _@1
MOV AX,WORD PTR [BP-2]
_PopAll
ADD SP,4
MOV SP,BP
POP BP
RET 4
_OutputNumber ENDP
_CopyNumeric PROC
LEA SI,num_1
LEA DI,num_3
MOV CX,size Numeric
REP MOVSB
RET
_CopyNumeric ENDP
_OutputNumeric PROC
PUSH BP
MOV BP,SP
SUB SP,2
_PushAll
MOV WORD PTR [BP-2],0
MOV SI,[BP+6]
MOV AX,[SI].Signed
TEST AX,AX
JE _@4
MOV AH,2
MOV DL,'('
INT 21H
MOV AH,2
MOV DL,'-'
INT 21H
_@4:
MOV AX,[BP+4]
TEST AX,AX
JNE _@5
MOV AX,[SI]
MOV DX,[SI+2]
MOV BX,10000
DIV BX
PUSH AX
PUSH [BP-2]
CALL _OutputNumber
MOV [BP-2],AX
PUSH DX
PUSH AX
CALL _OutputNumber
ADD [BP-2],AX
JMP _@7
_@5:
MOV CX,3
ADD SI,4
_@6:
MOV AX,[SI]
PUSH AX
PUSH [BP-2]
CALL _OutputNumber
ADD [BP-2],AX
SUB SI,2
LOOP _@6
_@7:
MOV AX,[BP-2]
TEST AX,AX
JNE _@8
MOV AH,2
MOV DL,030H
INT 21H
_@8:
MOV SI,[BP+6]
MOV AX,[SI].Signed
TEST AX,AX
JE _OnEnd
MOV AH,2
MOV DL,')'
INT 21H
_OnEnd:
_PopAll
ADD SP,2
MOV SP,BP
POP BP
RET 4
_OutputNumeric ENDP
code ends
END _start