📄 calculator.asm
字号:
;*********************
;the calculator's usage!
;after you have inputed 2 operators,choose + - * / function!
;But the only situation I did't deal with is that
;when you choos + fuction ,and the operaters signs is like this
;-A+B,just turn it to B-A!
;*********************
DATA SEGMENT
OP1 DB 41 DUP(0)
OP2 DB 41 DUP(0)
OP1NUM DW 0 ;save the number of op1
OP2NUM DW 0 ;save the number of op2
DOP1 DB 40 DUP(0) ;the buffer for div function
DOP2 DB 40 DUP(0)
MULB1 DB 41 DUP(0)
MULB2 DB 80 DUP(50H)
DIVR DB 40 DUP(50H)
STR1 DB 'Please Input The 1st Number',13,10,'$'
STR2 DB 'Please Input The 2st Number',13,10,'$'
STR3 DB 'The Answer Is:','$'
STR4 DB 'PLEASE CHOOSE THE FUNCTION +,-,* OR /?',13,10,'$'
STR5 DB 'ERROR','$'
STR6 DB 'TRY IT AIGIN?Y/N$'
STR7 DB '.....','$'
SIGNS1 DB 0 ;1 stands for minus signs
SIGNS2 DB 0
s_point dw 0
d_point dw 0
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START:
MOV AX,DATA
MOV DS,AX
ALL_AGAIN:
CALL ONE ;the proc print enter and space
MOV SI,0
LEA DX,STR1
MOV AH,09H
INT 21H
MOV AH,01H
INT 21H
CMP AL,2DH ;the sign is -?
JNZ LL0
ADD SIGNS1,1 ;save the signs
JMP L0
;--------------
LL0:
SUB AL,30H
CMP AL,09H
JA L0
JMP LL1
L0:MOV AH,01H
INT 21H
sub al,30h ;save THE INPUT NUMBER AS BCD CODE
LL1:
MOV OP1[SI+1],AL ;PUT IT INTO THE BUFFER
ADD AL,30H ;TO CMPARE WITH THE 0DH
INC SI
CMP AL,0DH
JNZ L0
mov op1[si],0 ;CLEAR THE 'ENTER' KEY'S CODE,'ODH'
dec si ;COUNT THE NUBER WE HAVE INPUT
SUB BX,BX
MOV BX,SI
MOV OP1NUM,BX
;-------------
CALL ONE
MOV SI,0
LEA DX,STR2
MOV AH,09H
INT 21H
MOV AH,01H
INT 21H
CMP AL,2DH
JNZ LLL0
ADD SIGNS2,1
JMP L1
LLL0:
SUB AL,30H
CMP AL,09H
JA L1
JMP LLL1
L1:MOV AH,01H
INT 21H
SUB AL,30H
LLL1:
MOV OP2[SI+1],AL
ADD AL,30H
INC SI
CMP AL,0DH
JNZ L1
;SUB SI,40 ;THE OFFSET DIFFERENCE
MOV OP2[SI],0 ;INT ORDER TO CLAER THE 'ODH',CHAGE IT INTO 0
dec si
SUB BX,BX
MOV BX,SI
MOV OP2NUM,BX
;-------CHOOSE FUNCTION----
CALL ONE
LEA DX,STR4
MOV AH,09H
INT 21H
C_AGAIN:
MOV AH,01H
INT 21H
CMP AL,'+'
JZ ADD_F
CMP AL,'-'
JZ SUB_F
CMP AL,'*'
JZ MUL_F
CMP AL,'/'
JZ DIV_F1
JMP C_AGAIN
;-----CHOOSE FUNCTION END ---
;-----------SUB FUNCITON--------
SUB_F:
sub ax,ax
MOV AL,1
CMP AL,SIGNS1
JNZ CCCM
CMP SIGNS2,0
JZ ADD_F
CCCM:
SUB AX,AX
MOV AL,1
ADD AL,SIGNS2
CMP AL,SIGNS1;the sign is,-&+ ?
JNZ SUBSTART
JMP CALLSTOA;if the sign is -,+,call the proc
SUBSTART:
CALL ONE
CALL SORT ;resort the op1&op2 buffer,from the end
sub bx,bx
sub ax,ax
MOV ax,OP1NUM
MOV bx,OP2NUM
mov si,40
mov di,40
sub si,ax
INC si
mov s_point,si
sub DI,BX
INC di
mov d_point,DI
CMP SI,DI
JB SCMP;SI<DI,which means op1 is longer
sub cx,cx
mov cx,si;op2 is longer
sub cx,di
sub si,cx
jmp sreal
scmp:
sub cx,cx
mov cx,di
sub cx,si;the difference
sub di,cx
sreal:
MOV BL,OP1[SI]
CMP BL,OP2[DI]
JB S_LESS ;op1<op2
MOV DI,40
MOV CX,40
CLC
GOON22:
MOV AL,OP1[DI];op1>op2
SBB AL,OP2[DI]
AAS
MOV OP1[DI],AL
DEC DI
DEC CX
JNZ GOON22
SBB OP1[DI],0
LEA DX,STR3
MOV AH,09H
INT 21H
SUB AX,AX
MOV AL,SIGNS1
ADD AL,SIGNS2
CMP AL,2;the signs is -,-
JZ S_SKIP;
CMP AL,0;the signs is +,+
JMP S_OVER
S_SKIP:
MOV DL,2DH
MOV AH,02H
INT 21H
S_OVER:
MOV AX,41
SUB AX,OP1NUM
MOV SI,AX
DEC SI
MOV CX,OP1NUM
INC CX
;-----OUTPUT------
LP00:
MOV DL,OP1[si]
ADD DL,30H
MOV AH,02H
INT 21H
INC si
DEC CX
JNZ LP00
JMP ENDING
S_LESS:
CALL SV2
JMP ENDING
CALLSTOA:
CALL STTTA
JMP ENDING
;----SUB FUNCITON EDN------
;----ADD FUNCTION-----
ADD_F:
SUB AX,AX
MOV AL,SIGNS1
ADD AL,SIGNS2
MOV AH,1
CMP AH,AL
JZ SUBSTART
STOA:
CALL ONE
CALL SORT ;resort the buffer
MOV DI,40 ;SCAN IT FROM THE END OF BUFFER
mov cx,40
CLC ;CF->0
;----------------
GO_ON:
MOV AL,OP1[DI]
ADC AL, OP2[DI]
AAA
MOV OP1[di],AL
dec di
dec cx
jnz GO_ON
ADC OP1[di],0
JMP READY
;----ADD FUNCTION END-----
DIV_F1:
JMP DIV_F
;-----MUL FUNCTION-------
MUL_F:
CALL ONE
CALL SORT
MOV DI,40
MOV DX,40
;---部分积置零------
MLOOP:
MOV SI,0
MOV CX,41
MLOOP1:
MOV MULB1[SI],0
INC SI
DEC CX
JNZ MLOOP1
;---------
MOV SI,40
MOV CX,40 ;NOT 41 ,THE TOP OF the BUFFER IS 0
CLC
MLOOP2:
MOV AL,OP1[SI]
MUL OP2[DI]
AAM
ADC AL,MULB1[SI]
AAA
MOV MULB1[SI],AL
MOV MULB1[SI-1],AH ;save the cf
DEC SI
DEC CX
JNZ MLOOP2
;----------------------
MOV SI,40
MOV CX,41
CLC
MLOOP3:
MOV AL,MULB1[SI] ;mov the first result to the final buffer
ADC AL,MULB2[DI+39]
AAA
MOV MULB2[DI+39],AL
DEC SI
DEC DI
DEC CX
JNZ MLOOP3 ;the pointer poin to the 2nd bit of op2
;--------------------
ADD DI,41
DEC DI
DEC DX
CMP DL,0
JNZ MLOOP
;----------------------
SUB AX,AX
SUB BX,BX
MOV AX,OP1NUM
CMP AX,OP2NUM
JB MMOUT ;the op2 is longer
SUB AX,AX
SUB BX,BX
MOV BL,2
MOV AX,OP1NUM
MUL BL
MOV CX,AX
SUB AX,AX
MOV AX,80
SUB AX,CX
MOV SI,AX
jmp MMMOUT
MMOUT:
SUB AX,AX
SUB BX,BX
MOV BL,2
MOV AX,OP2NUM
MUL BL
MOV CX,AX
SUB AX,AX
MOV AX,80
SUB AX,CX
MOV SI,AX
MMMOUT:
LEA DX,STR3
MOV AH,09H
INT 21H
;----------
MOV AL,SIGNS1
add AL,SIGNS2
cmp al,2
JZ MLOOP6
cmp al,0
jz MLOOP6
MOV DL,2DH
MOV AH,02H
INT 21H
;------------
MLOOP6:
MOV AL,MULB2[SI]
CMP AL,50H
JZ MLOOP7
MOV DL,AL
ADD DL,30H
MOV AH,02H
INT 21H
MLOOP7:
INC si
DEC CX
JNZ MLOOP6
JMP ENDING
;----MUL FUNCTION END------
;------DIV FUNCTION----------
DIV_F:
CALL SORT
CALL SORT1
CALL ONE
MOV SI,0
MOV CX,40
SUB AX,AX
D_SKIP:
ADD AL,DOP2[SI] ;just scan if the op2 is zero?
INC SI
DEC CX
JNZ D_SKIP
CMP AL,0
JZ DERROR1
JMP D_B
DERROR1:JMP DERROR
D_B:
MOV SI,40
D_C:DEC SI
MOV AL,DOP1[SI]
CMP AL,DOP2[SI]
JB D_OUT ;if the op1<op2 just output
JZ D_C
CLC
MOV SI,0
SUB AX,AX
MOV CX,40
D_S:MOV AL,DOP1[SI] ;just use the sub for loop
SBB AL,DOP2[SI]
AAS
MOV DOP1[SI],AL
INC SI
INC DI
DEC CX
JNZ D_S
CLC
MOV SI,0
MOV CX,39
SUB AX,AX
MOV AL,DIVR[SI] ; the quotient's counter++ after the sub
ADD AL,1
AAA
MOV DIVR[SI],AL ;save it
D_LL:
INC SI
MOV AL,DIVR[SI]
ADC AL,0
AAA
MOV DIVR[SI],AL
DEC CX
JNZ D_LL
JMP D_B
D_OUT:
LEA DX,STR3
MOV AH,09H
INT 21H
;-----------
MOV AL,SIGNS1
CMP AL,SIGNS2
JZ DLLP ; the sign contains no sign of '-'
MOV DL,2DH
MOV AH,02H
INT 21H
;-----------
DLLP:
MOV CX,op1num
MOV SI,cx
DEC SI
D_LL2:
MOV AL,DIVR[SI]
CMP AL,50H
JZ D_LL4
MOV DL,AL
ADD DL,30H
MOV AH,02H
INT 21H
D_LL4:
DEC SI
DEC CX
JNZ D_LL2
MOV SI,0
MOV CX,40
SUB AX,AX
D_SCAN:
ADD AL,DOP1[SI]
INC SI
DEC CX
JNZ D_SCAN ;just scan if the result contains remainder
CMP AL,0
JZ DSKIP ;yes,print the '......'
LEA DX,STR7
MOV AH,09H
INT 21H
SUB CX,CX
MOV SI,39
MOV CX,40
D_LL3:
MOV AL,DOP1[SI]
CMP AL,0
JZ D_LL5
MOV DL,AL
ADD DL,30H
MOV AH,02H
INT 21H
D_LL5:
DEC SI
DEC CX
JNZ D_LL3
DSKIP:
JMP ENDING
;-----DIV FUNCTION END----
READY:
LEA DX,STR3
MOV AH,09H
INT 21H
SUB AX,AX
MOV AL,SIGNS1
ADD AL,SIGNS2
CMP AL,2;the sign is -,-
JNZ AV_SKIP;
MOV DL,2DH
MOV AH,02H
INT 21H
AV_SKIP:
SUB AX,AX
SUB BX,BX
MOV AX,OP1NUM
CMP AX,OP2NUM
JB ROUT ;THE OP2 IS LONGER
MOV BX,41
SUB BX,OP1NUM
MOV SI,BX
DEC SI
MOV CX,OP1NUM
INC CX
JMP LP
ROUT:
MOV BX,41
SUB BX,OP2NUM
MOV SI,BX
DEC SI
MOV CX,OP2NUM
INC CX
;-----OUTPUT------
LP:
MOV DL,OP1[si]
ADD DL,30H
MOV AH,02H
INT 21H
INC si
DEC CX
JNZ LP
ENDING:
CALL ONE
LEA DX,STR6
MOV AH,09H
INT 21H
MOV AH,01H
INT 21H
CMP AL,59H ;choose Y?
JNZ AQUIT
CALL CLEAN
JMP ALL_AGAIN
AQUIT:
MOV AH,4CH
INT 21H
DERROR:
LEA DX,STR5
MOV AH,09H
INT 21H
JMP ENDING
ONE PROC NEAR ;the funciton is to print the enter and space
PUSH DX
MOV DL,0DH
MOV AH,02H
INT 21H
MOV DL,0AH
MOV AH,02H
INT 21H
POP DX
RET
ONE ENDP
CLEAN PROC NEAR
PUSH CX
PUSH SI
SUB CX,CX
MOV SI,0
MOV CX,41
C_L1:
MOV OP1[SI],0
MOV OP2[SI],0
MOV MULB1[SI],0
INC SI
DEC CX
JNZ C_L1
SUB CX,CX
MOV SI,0
MOV CX,40
C_L2:
MOV DOP1[SI],0
MOV DOP2[SI],0
MOV DIVR[SI],0
INC SI
DEC CX
JNZ C_L2
SUB CX,CX
MOV SI,0
MOV CX,80
C_L3:MOV MULB2[SI],0
INC SI
DEC CX
JNZ C_L3
MOV SIGNS1,0
MOV SIGNS2,0
POP SI
POP CX
RET
CLEAN ENDP
SORT1 PROC NEAR ;the function is for the div funciton
PUSH AX
PUSH CX
PUSH SI
PUSH DI
SUB AX,AX
SUB CX,CX
MOV SI,40
MOV DI,0
MOV CX,40
S1_L1:
MOV AL,OP1[SI]
MOV DOP1[DI],AL
DEC SI
INC DI
DEC CX
JNZ S1_L1
SUB AX,AX
SUB CX,CX
MOV SI,40
MOV DI,0
MOV CX,40
S1_L2:
MOV AL,OP2[SI]
MOV DOP2[DI],AL
DEC SI
INC DI
DEC CX
JNZ S1_L2
POP DI
POP SI
POP CX
POP AX
RET
SORT1 ENDP
SORT PROC NEAR ;resort the buffer to the end
PUSH AX
PUSH CX
PUSH SI
PUSH DI
SUB AX,AX
SUB CX,CX
MOV SI,0
MOV AX,OP1NUM
ADD SI,AX
MOV DI,40
MOV CX,AX
S_L:
MOV AL,OP1[SI]
MOV OP1[SI],0
MOV OP1[DI],AL
DEC SI
DEC DI
DEC CX
JNZ S_L
MOV SI,0
SUB AX,AX
SUB CX,CX
MOV AX,OP2NUM
ADD SI,AX
MOV DI,40
MOV CX,AX
S_L1:
MOV AL,OP2[SI]
MOV OP2[SI],0
MOV OP2[DI],AL
DEC SI
DEC DI
DEC CX
JNZ S_L1
POP DI
POP SI
POP CX
POP AX
RET
SORT ENDP
SV2 PROC NEAR ;the sub situation of op1<op2
MOV DI,40
MOV CX,40
CLC
LGOON:
MOV AL,OP2[DI]
SBB AL,OP1[DI]
AAS
MOV OP2[DI],AL
DEC DI
DEC CX
JNZ LGOON
SBB OP2[DI],0
LEA DX,STR3
MOV AH,09H
INT 21H
SUB AX,AX
MOV AL,SIGNS1
ADD AL,SIGNS2
CMP AL,2 ;the sign is -,-
JZ Sv2_SKIP;
MOV DL,2DH
MOV AH,02H
INT 21H
Sv2_SKIP:
SUB AX,AX
SUB BX,BX
MOV AX,OP1NUM
CMP AX,OP2NUM
JB OP2OUT ;the OP2 is longer
MOV BX,41
SUB BX,OP1NUM
MOV SI,BX
DEC SI
MOV CX,OP1NUM
INC CX
JMP SV2_LP
OP2OUT:
MOV BX,41
SUB BX,OP2NUM
MOV SI,BX
DEC SI
MOV CX,OP2NUM
INC CX
SV2_LP:
MOV DL,OP2[si]
ADD DL,30H
MOV AH,02H
INT 21H
INC si
DEC CX
JNZ SV2_LP
RET
SV2 ENDP
STTTA PROC NEAR ;the sub's situation of -&+
CALL ONE
CALL SORT
MOV DI,40 ;SCAN IT FROM THE END OF BUFFER
mov cx,40
CLC ;CF->0
;-------
GO_ONSTOA:
MOV AL,OP1[DI]
ADC AL, OP2[DI]
AAA
MOV OP1[di],AL
dec di
dec cx
jnz GO_ONSTOA
ADC OP1[di],0
LEA DX,STR3
MOV AH,09H
INT 21H
MOV DL,2DH
MOV AH,02H
INT 21H
SUB AX,AX
SUB BX,BX
MOV AX,OP1NUM
CMP AX,OP2NUM
JB SSTOA;THE OP2 IS LONGER
MOV BX,41
SUB BX,OP1NUM
MOV SI,BX
DEC SI
MOV CX,OP1NUM
INC CX
JMP LP
SSTOA:
MOV BX,41
SUB BX,OP2NUM
MOV SI,BX
DEC SI
MOV CX,OP2NUM
INC CX
LPSTOA:
MOV DL,OP1[si]
ADD DL,30H
MOV AH,02H
INT 21H
INC si
DEC CX
JNZ LPSTOA
RET
STTTA ENDP
CODE ENDS
END START
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -