?? ca.asm
字號:
;############## CALCULATOR ########################
DATA SEGMENT
X DW 0,0
Y DW 0,0
BUF DW 0,0
RESULT DW 0,0,0,0
OUTSTRING DB 12 DUP(0) ;output string
SIGN DB 0
OPERATOR DB 0
TAG DB ? ;label for repeat or not
FLAG DB 0 ;if(FLAG==0) then '0' will not be outputed
DCB DW 17H,4876H,0E800H, 2H,540BH,0E400H, 0,3B9AH,0CA00H,0,5F5H,0E100H,0,98H,9680H,0,0FH,4240H,0,1H,86A0H,0,0,2710H,0,0,3E8H,0,0,64H,0,0,0AH,0,0,1H
; 10^11,10^10,...,10,1
M1 DB 'PLEASE ENTER THE FIRST OPERAND: $'
M2 DB 'PLEASE ENTER THE SECOND OPERAND: $'
OPR DB 'PLEASE SECLECT OPERATOR 1)+ 2)- 3)* 4)/ : $'
ERR DB 'INPUT ERROR!$ '
RES DB 'RESULT IS: $'
AGAIN DB 'WOULD YO LIKE TO DO AGAIN (Y/N)? $'
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START:
MAIN PROC FAR
MOV AX,DATA
MOV DS,AX
REPEAT: MOV BX,10
MOV SIGN,0 ;sign of the result
MOV TAG,0
CALL INPUT1
CALL INPUT2
CALL SELECT ;select operator
MOV DL,13 ;next line
MOV AH,02H
INT 21H
MOV DL,10
MOV AH,02H
INT 21H
MOV AL,OPERATOR
CMP AL,1
JNZ L0
CALL A ;add
JMP L3
L0: CMP AL,2
JNZ L1
CALL S ;subtract
JMP L3
L1: CMP AL,3
JNZ L2
CALL M ;multiply
JMP L3
L2: CMP AL,4
JNZ L3
CALL D ;divided by
L3: MOV DL,13 ;next line
MOV AH,02H
INT 21H
MOV DL,10
MOV AH,02H
INT 21H
CALL RE ;ask if repeat
MOV DL,13
MOV AH,02H
INT 21H
MOV DL,10
MOV AH,02H
INT 21H
MOV AL,TAG
CMP AL,1
JZ REPEAT
MOV AH,4CH ;over
INT 21H
MAIN ENDP
;############### ENTER THE FIRST OPRAND ###################
INPUT1 PROC NEAR
MOV CX,6 ;for 6 bit of decimal most
MOV X,0 ;let x=0 in case calculation is doing for more than once
MOV X+2,0
LEA DX,M1
MOV AH,09H
INT 21H
L4: MOV AH,01H
INT 21H
CMP AL,0DH ;when receive 'enter' cease the input
JZ L5
SUB AL,30H ;if (AL) < 0 , error
JC NEXT1
CMP AL,0AH
JNC NEXT1 ;if (AL) >10, error
MOV AH,0
MOV BUF,AX
MOV AX,X+2 ; x = x*10 + (Al)
MUL BX
MOV X+2,AX
MOV AX,X
MOV DX,0
MUL BX
ADD AX,BUF
MOV X,AX
ADC X+2,DX
LOOP L4
JMP L5
NEXT1: LEA DX,ERR ;error
MOV AH,09H
INT 21H
L5: MOV DL,13 ;next line
MOV AH,02H
INT 21H
MOV DL,10
MOV AH,02H
INT 21H
RET
INPUT1 ENDP
;################ ENTER THE SECOND OPERAND #######################
INPUT2 PROC NEAR
MOV CX,6 ;for 6 bit of decimal most
MOV Y,0 ;let y=0 in case calculation is doing for more than once
MOV Y+2,0
LEA DX,M2
MOV AH,09H
INT 21H
L6: MOV AH,01H
INT 21H
CMP AL,0DH ;when receive 'enter' cease the input
JZ L7
SUB AL,30H
JC NEXT2
CMP AL,0AH
JNC NEXT2
MOV AH,0
MOV BUF,AX
MOV AX,Y+2
MUL BX
MOV Y+2,AX ;much the same as 'INPUT1'
MOV AX,Y
MOV DX,0
MUL BX
ADD AX,BUF
MOV Y,AX
ADC Y+2,DX
LOOP L6
JMP L7
NEXT2: LEA DX,ERR
MOV AH,09H
INT 21H
L7: MOV DL,13
MOV AH,02H
INT 21H
MOV DL,10
MOV AH,02H
INT 21H
RET
INPUT2 ENDP
;################ SELECT OPRATOR #####################
SELECT PROC NEAR ;select from 1 to 4
LEA DX,OPR ; 1----add
MOV AH,09H ; 2----subtract
INT 21H ; 3----multiply
MOV AH,01H ; 4----divided by
INT 21H
SUB AL,30H
CMP AL,1
JC NEXT3
CMP AL,5
JNC NEXT3
MOV OPERATOR,AL
RET
NEXT3: LEA DX,ERR
MOV AH,09H
INT 21H
RET
SELECT ENDP
;#################### ADD ############################
A PROC NEAR
MOV AX,X
ADD AX,Y ;simply add x and y
MOV RESULT,AX ;keep the result
MOV AX,X+2
ADC AX,Y+2
MOV RESULT+2,AX
LEA DX,RES ;output
MOV AH,09H
INT 21H
CALL OUTPUT1
RET
A ENDP
;############### SUBTRACT ############################
S PROC NEAR
MOV AX,X+2
CMP AX,Y+2 ;compare x and y
JNBE L8 ;if x >= y, sign = 0, result = x - y
JB L9 ;if x < y, sign = 1, result = y - x
MOV AX,X
CMP AX,Y
JB L9
L8: MOV AX,X
SUB AX,Y
MOV RESULT,AX
MOV AX,X+2
SBB AX,Y+2
MOV RESULT+2,AX
RET
L9: MOV SIGN,1 ;result is negative
MOV AX,Y
SUB AX,X
MOV RESULT,AX ;keep the result
MOV AX,Y+2
SBB AX,X+2
MOV RESULT+2,AX
LEA DX,RES ;output
MOV AH,09H
INT 21H
CALL OUTPUT1
RET
S ENDP
;############## MULTIPLY ##############################
M PROC NEAR
CLC
MOV AX,X
MOV DX,0
MOV BX,Y
MUL BX ; x*y --->result,result+2
MOV RESULT,AX
MOV RESULT+2,DX
MOV AX,X+2
MOV DX,0
MUL BX ; (x+2)*y --->result+2,result+4
ADD RESULT+2,AX
ADC RESULT+4,DX
MOV AX,X
MOV DX,0
MOV BX,Y+2
MUL BX ; x*(y+2) --->result+2,result+4
ADD RESULT+2,AX
ADC RESULT+4,DX
MOV AX,X+2
MOV DX,0
MUL BX ; (x+2)*(y+2) --->result+4,result+6
ADC RESULT+4,AX
ADC RESULT+6,DX
LEA DX,RES ;calculate and output
MOV AH,09H
INT 21H
CALL OUTPUT1
RET
M ENDP
;############### DIVIDED BY ############################
D PROC NEAR ;result+4,result+6 is the quotient, result,result+2 is the remain
MOV CX,0 ;cx reserve result+4's value
MOV DX,0 ;dx reserve result+6's value
CMP Y+2,0
JNZ L10
CMP Y,0
JNZ L10
LEA DX,ERR
MOV AH,09H
INT 21H
RET
L10: MOV AX,X+2 ;compare x and y
CMP AX,Y+2 ;if x >= y
JNBE L13 ;then (cx)+1 --> cx, and (dx) + carry ---> dx
JE L12 ;if x < y
L11: MOV AX,X ;then x--->result,result+2
MOV RESULT,AX ;and (cx),(dx) --->result+4,result+6
MOV AX,X+2
MOV RESULT+2,AX
MOV RESULT+4,CX
MOV RESULT+6,DX
LEA DX,RES ; output
MOV AH,09H
INT 21H
CALL OUTPUT2
RET
L12: MOV AX,X
CMP AX,Y
JNB L13
JMP L11
L13: ADD CX,1
ADC DX,0
MOV AX,X
SUB AX,Y
MOV X,AX
MOV AX,X+2
SBB AX,y+2
MOV X+2,AX
JMP L10
RET
D ENDP
;############## OUTPUT1(FOR ADD,SUBTRACT,MULTIPLY) ##########
OUTPUT1 PROC NEAR ;similar to the division
MOV DL,0
MOV BX,0 ;compare with 10^n,(0<= n <= 11)
MOV SI,0
MOV AL,SIGN ;if (result >= 10^n)
CMP AL,1
JNZ L14 ;{ (dl)+1 ---> dl
MOV DL,'-'
MOV AH,02H ; result - 10^n ---> [result]
INT 21H
MOV DL,0 ; compare with 10^n again }
L14: MOV AX,RESULT+4
CMP AX,DCB[SI] ;else
JNBE L16
JB L15 ;{ (dl) ---> outstring[bx]
MOV AX,RESULT+2
CMP AX,DCB[SI+2] ; (si)+6 ---> si
JNBE L16
JB L15 ; (bx)+1 ---> bx
MOV AX,RESULT
CMP AX,DCB[SI+4] ; compare with 10^n-1 }
JNB L16
L15: MOV OUTSTRING[BX],DL
ADD SI,6
MOV DL,0
INC BX
CMP BX,12
JNZ L14
JMP L17
L16: INC DL
MOV AX,RESULT
SUB AX,DCB[SI+4]
MOV RESULT,AX
MOV AX,RESULT+2
SBB AX,DCB[SI+2]
MOV RESULT+2,AX
MOV AX,RESULT+4
SBB AX,DCB[SI]
MOV RESULT+4,AX
JMP L14
L17: MOV CX,12
MOV SI,0
L18: MOV DL,OUTSTRING[SI] ;output the bcd string
CMP DL,0
JNE L19
CMP FLAG,0
JNE L19
JMP L20
L19: MOV FLAG,1
ADD DL,30H
MOV AH,02H
INT 21H
L20: INC SI
LOOP L18
CMP FLAG,0
JNE L21
MOV DL,'0'
MOV AH,02H
INT 21H
L21: MOV FLAG,0
RET
OUTPUT1 ENDP
;########### OUTPUT2 (FOR DIVIDED) ######################
OUTPUT2 PROC NEAR
MOV AX,RESULT ;first output the quotient
MOV BUF,AX
MOV AX,RESULT+2
MOV BUF+2,AX
MOV AX,RESULT+4
MOV RESULT,AX
MOV AX,RESULT+6
MOV RESULT+2,AX
MOV RESULT+4,0
MOV RESULT+6,0
CALL OUTPUT1
MOV DL,'.' ;then output the remain
MOV AH,02H
INT 21H
MOV DL,'.'
MOV AH,02H
INT 21H
MOV DL,'.'
MOV AH,02H ;use the output1 twice
INT 21H
MOV AX,BUF
MOV RESULT,AX
MOV AX,BUF+2
MOV RESULT+2,AX
CALL OUTPUT1
RET
OUTPUT2 ENDP
;################ REPEAT? ##############################
RE PROC NEAR
LEA DX,AGAIN
MOV AH,09H
INT 21H
MOV AH,01H
INT 21H
CMP AL,'Y'
JNZ L22
MOV TAG,1
RET
L22: CMP AL,'y'
JNZ L23
MOV TAG,1
RET
L23: RET
RE ENDP
;########################################################
CODE ENDS
END START
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -