?? cal(16dos).asm
字號:
;TITLE CALCULATOR
;--------------------------------------------------------------------------------------------------------------------------------
; Purpose
; Programmer Sun
; FileName .ASM
;--------------------------------------------------------------------------------------------------------------------------------
.286
.MODEL SMALL
.STACK 128
.DATA
;DEFINITIONS
MAX EQU 0CH
LENTH DB MAX
RESULT1 DB MAX DUP(0)
RESULT2 DB MAX DUP(0),'$'
NUM1 DB 31H,30H,30H,30H,30H,30H,30H,30H,30H,32H,35H,38H,'$' ;A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12
NUM2 DB 30H,30H,31H,30H,30H,30H,30H,30H,30H,30H,30H,30H,'$' ;B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12
SIGN DB '*','$'
ADDRESS1 DW ?
ADDRESS2 DW ?
ADDRESS3 DW ?
ADDRESS4 DW ?,'$'
NUMBER DB ?
FLAG DW 0001H
TEMP1 DB MAX DUP(0)
TEMP2 DB MAX DUP(0),'$'
TEMP3 DB MAX DUP(0),'$'
;--------------------------------------------------------------------------------------------------------------------------------
.CODE
START PROC NEAR
MOV AX,@DATA
MOV DS,AX
MOV ES,AX
;--------------------------------------------------------------------------------------------------------------------------------
;CODES
;;---------------------------modify the input from ASCII to binary code
ENTER 2,0
LEA AX,NUM1
MOV WORD PTR [BP-2],AX
CALL ASCIITOBIN
LEAVE
ENTER 2,0
LEA AX,NUM2
MOV WORD PTR [BP-2],AX
CALL ASCIITOBIN
LEAVE
;;---------------------------
CMP SIGN,2AH
JNZ A10
ENTER 8,0
LEA AX,NUM1
MOV WORD PTR [BP-2],AX ;transmit the address of array num1
LEA AX,NUM2
MOV WORD PTR [BP-4],AX ;transmit the address of array num2
LEA AX,RESULT1
MOV WORD PTR [BP-6],AX ;transmit the address of array result1
LEA AX,RESULT2
MOV WORD PTR [BP-8],AX ;transmit the address of array result2
CALL MULTIPLICATION
LEAVE
JMP A40
A10:
CMP SIGN,2BH
JNZ A20
ENTER 6,0
LEA AX,NUM1
MOV WORD PTR [BP-2],AX
LEA AX,NUM2
MOV WORD PTR [BP-4],AX
LEA AX,RESULT2
MOV WORD PTR [BP-6],AX
CALL ADDITION
LEAVE
JMP A40
A20:
CMP SIGN,2DH
JNZ A30
ENTER 6,0
LEA AX,NUM1
MOV WORD PTR [BP-2],AX
LEA AX,NUM2
MOV WORD PTR [BP-4],AX
LEA AX,RESULT2
MOV WORD PTR [BP-6],AX
CALL SUBTRACTION
LEAVE
JMP A40
A30:
CMP SIGN,2FH
JNZ A40
ENTER 8,0
LEA AX,NUM1
MOV WORD PTR [BP-2],AX
LEA AX,NUM2
MOV WORD PTR [BP-4],AX
LEA AX,RESULT1
MOV WORD PTR [BP-6],AX
LEA AX,RESULT2
MOV WORD PTR [BP-8],AX
CALL DIVITION
LEAVE
A40:
;;---------------------------modify the output binary code from to ASCII
CMP SIGN,2AH
JZ B10
CMP SIGN,2FH
JZ B20
CMP SIGN,2BH
JZ B30
CMP SIGN,2DH
JZ B30
JMP B40
B10:
MOV AL,LENTH ;modify LENTH
SHL AL,01H
MOV LENTH,AL
ENTER 2,0
LEA AX,RESULT1
MOV WORD PTR [BP-2],AX
CALL BINTOASCII
LEAVE
MOV AL,LENTH ;modify LENTH
SHR AL,02H
MOV LENTH,AL
JMP B40
B20:
ENTER 2,0
LEA AX,RESULT1
MOV WORD PTR [BP-2],AX
CALL BINTOASCII
LEAVE
B30:
ENTER 2,0
LEA AX,RESULT2
MOV WORD PTR [BP-2],AX
CALL BINTOASCII
LEAVE
B40:
;;---------------------------
MOV AH,09H
LEA DX,result1
INT 21H
MOV AH,4CH
INT 21H
RET
START ENDP
;--------------------------------------------------------------------------------------------------------------------------------
ASCIITOBIN PROC NEAR
PUSH ADDRESS1
PUSHA
PUSHF
MOV AX,[BP-2]
MOV ADDRESS1,AX
;;---------------------------initialize array temp[] as 00000...
LEA DI,TEMP3
MOV CH,00H
MOV CL,LENTH
ASCIITOBIN10:
MOV AL,00H
MOV BX,CX
MOV [DI+BX-1],AL
DEC CX
JNZ ASCIITOBIN10
;;---------------------------
MOV CH,00H
MOV CL,LENTH
MOV DI,ADDRESS1
ASCIITOBIN20:
MOV AL,[DI]
AND AL,0FH
MOV [DI],AL
INC DI
DEC CX
JNZ ASCIITOBIN20
MOV CH,00H
MOV CL,LENTH
MOV DI,ADDRESS1
ASCIITOBIN30: ;NUM=(...(NUM[0]*0AH+NUM[1])*0AH)*...)+NUM[MAX-1]
;temp1=temp1*0AH+NUM[i]
;;; NUM is an array of ASCII '0'~'9', therefor the value: NUM=(...(NUM[0]*10+NUM[1])*10)*...)+NUM[MAX-1] is
;;; smaller than FFF...F (MAX F). TEMP3 is enough for NUM as hexadecimal code
MOV DL,BYTE PTR [DI]
ENTER 5,0 ;TEMP1=TEMP3*0AH
LEA AX,TEMP3
MOV WORD PTR [BP-2],AX
MOV AH,0AH
MOV BYTE PTR [BP-3],AH
LEA AX,TEMP1
MOV WORD PTR [BP-5],AX
CALL MULTIPLY
LEAVE
PUSH CX
PUSH DI
MOV CH,00H ;TEMP3=TEMP1[LENTH,2*LENTH-1]
MOV CL,LENTH
LEA DI,TEMP3
LEA SI,TEMP2
REP MOVSB
POP DI
POP CX
PUSHF ;save ZF
MOV BH,00H ;TEMP3=TEMP3+NUM[i]
MOV BL,LENTH
MOV AL,BYTE PTR TEMP3[BX-1]
ADD AL,DL
MOV BYTE PTR TEMP3[BX-1],AL
DEC BX
ASCIITOBIN40:
ADC BYTE PTR TEMP3[BX-1],00H
DEC BX
JNZ ASCIITOBIN40
POPF ;pop ZF
INC DI
DEC CX
JNZ ASCIITOBIN30
MOV CH,00H
MOV CL,LENTH
MOV DI,ADDRESS1
LEA SI,TEMP3
REP MOVSB
POPF
POPA
POP ADDRESS1
RET
ASCIITOBIN ENDP
;--------------------------------------------------------------------------------------------------------------------------------
BINTOASCII PROC NEAR
PUSH ADDRESS1
PUSHA
PUSHF
MOV AX,[BP-2]
MOV ADDRESS1,AX
MOV SI,ADDRESS1
MOV CH,00H
MOV CL,LENTH
LEA DI,TEMP1
REP MOVSB
;;;RESULT is not set to 000...0 because there will be more numbers in an uncompressed BCD code than a hexadecimal code,
;;;thus, the old numbers in RESULT will all be replace in the process
MOV SI,ADDRESS1 ;start division
MOV CH,00H
MOV CL,LENTH
ADD SI,CX
MOV DH,0AH
BINTOASCII10:
; a division round starts
; in every division, the quotient will be same in temp1 sequently as a divident later, and the last reminder
; will be saved as result(the ASCII code)
MOV CH,00H
MOV CL,LENTH
LEA DI,TEMP1
MOV AH,00H ;AH is set to 00H, later the remind of a early division will be left in AH
MOV DL,00H ;DL is used to save CX(DL=CL) the first time when the quotient AL!=0
BINTOASCII20:
MOV AL,[DI]
DIV DH ;AX/DH, leaving quotient in AL, reminder in AH
CMP AL,00H ;the quotient AL!=0 ?
JZ BINTOASCII30
CMP DL,00H ;DL is modified to 00H at the beginning
JNZ BINTOASCII30
MOV DL,CL ;save CX: the first time when quotient AL!=0
BINTOASCII30:
MOV [DI],AL ;save the quotient AL, TEMP1 will be used as a divident later
INC DI
DEC CX
JNZ BINTOASCII20
DEC SI
MOV [SI],AH ;AH is the last reminder of a division round(a division round is between BINTOASCII10)
CMP DL,00H
JNZ BINTOASCII10
MOV CH,00H
MOV CL,LENTH
MOV DI,ADDRESS1
BINTOASCII40:
MOV AL,[DI]
OR AL,30H
MOV [DI],AL
INC DI
DEC CX
JNZ BINTOASCII40
POPF
POPA
POP ADDRESS1
RET
BINTOASCII ENDP
;--------------------------------------------------------------------------------------------------------------------------------
ADDITION PROC NEAR
PUSH ADDRESS1
PUSH ADDRESS2
PUSH ADDRESS3
PUSHA
PUSHF
MOV AX,[BP-2]
MOV ADDRESS1,AX
MOV AX,[BP-4]
MOV ADDRESS2,AX
MOV AX,[BP-6]
MOV ADDRESS3,AX
CLC
MOV CH,00H
MOV CL,LENTH
A50:
MOV BX,CX
MOV SI,ADDRESS2
MOV AH,[SI+BX-1]
MOV DI,ADDRESS1
MOV AL,[DI+BX-1]
ADC AH,AL
MOV SI,ADDRESS3
MOV [SI+BX-1],AH
DEC CX
JNZ A50
;the problem of overflow is unsolved
POPF
POPA
POP ADDRESS3
POP ADDRESS2
POP ADDRESS1
RET
ADDITION ENDP
;------------------------------------------------
SUBTRACTION PROC NEAR
PUSH ADDRESS1
PUSH ADDRESS2
PUSH ADDRESS3
PUSHA
PUSHF
MOV AX,[BP-2]
MOV ADDRESS1,AX
MOV AX,[BP-4]
MOV ADDRESS2,AX
MOV AX,[BP-6]
MOV ADDRESS3,AX
MOV CL,LENTH
MOV CH,00H
A60:
MOV BX,CX
MOV SI,ADDRESS1
MOV AH,[SI+BX-1]
MOV SI,ADDRESS2
MOV AL,[SI+BX-1]
SBB AH,AL
MOV SI,ADDRESS3
MOV [SI+BX-1],AH
DEC CX
JNZ A60
;the problem of overflow is unsolved
POPF
POPA
POP ADDRESS3
POP ADDRESS2
POP ADDRESS1
RET
SUBTRACTION ENDP
;------------------------------------------------
MULTIPLICATION PROC NEAR
PUSH ADDRESS1
PUSH ADDRESS2
PUSH ADDRESS3
PUSH ADDRESS4
PUSHA
PUSHF
MOV AX,[BP-2]
MOV ADDRESS1,AX
MOV AX,[BP-4]
MOV ADDRESS2,AX
MOV AX,[BP-6]
MOV ADDRESS3,AX
MOV AX,[BP-8]
MOV ADDRESS4,AX
;CCCCCC=AAA*BBB
MOV CH,00H
MOV CL,LENTH
MOV DI,ADDRESS2
A70:
ENTER 5,0
MOV AX,ADDRESS1
MOV WORD PTR [BP-2],AX
MOV AH,[DI]
MOV BYTE PTR [BP-3],AH
LEA AX,TEMP1
MOV WORD PTR [BP-5],AX
CALL MULTIPLY ;AAA*B
LEAVE
ENTER 2,0
MOV AX,ADDRESS3
MOV WORD PTR [BP-2],AX
CALL MOVERESULT
LEAVE
MOV AL,LENTH ;modify LENTH
SHL AL,01H
MOV LENTH,AL
ENTER 6,0
MOV AX,ADDRESS3
MOV WORD PTR [BP-2],AX
LEA AX,TEMP1
MOV WORD PTR [BP-4],AX
MOV AX,ADDRESS3
MOV WORD PTR [BP-6],AX
CALL ADDITION ;CCCCCC=CCCCCC+AAA*B
LEAVE
MOV AL,LENTH ;modify LENTH
SHR AL,01H
MOV LENTH,AL
INC DI
DEC CX
JNZ A70
POPF
POPA
POP ADDRESS4
POP ADDRESS3
POP ADDRESS2
POP ADDRESS1
RET
MULTIPLICATION ENDP
;------------------------------------------------
DIVITION PROC NEAR
PUSH ADDRESS1
PUSH ADDRESS2
PUSH ADDRESS3
PUSH ADDRESS4
PUSHA
PUSHF
MOV AX,[BP-2]
MOV ADDRESS1,AX
MOV AX,[BP-4]
MOV ADDRESS2,AX
MOV AX,[BP-6]
MOV ADDRESS3,AX
MOV AX,[BP-8]
MOV ADDRESS4,AX
MOV CH,00H
MOV CL,LENTH
MOV DI,ADDRESS4
MOV SI,ADDRESS1
REP MOVSB
MOV CH,00H
MOV CL,LENTH
MOV SI,ADDRESS4
ADD SI,CX
MOV AL,CL
MOV DH,08H
MUL DH
MOV CX,AX
A80:
ENTER 2,0 ;SHL result
MOV AX,ADDRESS3
MOV WORD PTR [BP-2],AX
CALL SHLRESULT
LEAVE
ENTER 6,0 ;examine if RESULT1>NUM2
MOV AX,ADDRESS2
MOV WORD PTR [BP-2],AX
MOV AX,ADDRESS3
MOV WORD PTR [BP-4],AX
MOV FLAG,0000H
LEA AX,FLAG
MOV [BP-6],AX
CALL BIGER
LEAVE
CMP FLAG,1111H ;result=result+01h
JNZ A90
MOV AL,[SI-1]
ADD AL,01H
MOV [SI-1],AL
ENTER 6,0
MOV AX,ADDRESS3
MOV WORD PTR [BP-2],AX
MOV AX,ADDRESS2
MOV WORD PTR [BP-4],AX
MOV AX,ADDRESS3
MOV WORD PTR [BP-6],AX
CALL SUBTRACTION ;result1=result1-num2
LEAVE
A90:
DEC CX
JNZ A80
POPF
POPA
POP ADDRESS4
POP ADDRESS3
POP ADDRESS2
POP ADDRESS1
RET
DIVITION ENDP
;------------------------------------------------
MULTIPLY PROC NEAR
PUSH ADDRESS1
PUSH ADDRESS2
PUSHA
PUSHF
MOV AX,[BP-2]
MOV ADDRESS1,AX
MOV AH,[BP-3]
MOV NUMBER,AH
MOV AX,[BP-5]
MOV ADDRESS2,AX
;;---------------------------initialize array temp[] as 00000...
MOV DI,ADDRESS2
MOV CH,00H
MOV CL,LENTH
SHL CX,01H
A100:
MOV AL,00H
MOV BX,CX
MOV [DI+BX-1],AL
DEC CX
JNZ A100
;;---------------------------
MOV CH,00H
MOV CL,LENTH
MOV DI,ADDRESS1
A110:
PUSHF ;save ZF
MOV AL,[DI] ;temp=temp*10H+Ai*Bi temp->ADDRESS2
MOV AH,00H
MUL NUMBER ;DX=Ai*Bi
MOV DX,AX
ENTER 2,0 ;temp=temp*10H
MOV AX,ADDRESS2
MOV WORD PTR [BP-2],AX
CALL MOVERESULT
LEAVE
MOV BH,00H ;temp=temp+Ai*Bi
MOV BL,LENTH
SHL BX,01H
MOV SI,ADDRESS2
MOV AL,BYTE PTR [SI+BX-1]
MOV AH,BYTE PTR [SI+Bx-2]
ADD AX,DX
MOV BYTE PTR [SI+BX-1],AL
MOV BYTE PTR [SI+BX-2],AH
DEC BX
DEC BX
A120:
ADC BYTE PTR [SI+BX-1],00H
DEC BX
JNZ A120
POPF ;pop ZF
INC DI
DEC CX
JNZ A110
POPF
POPA
POP ADDRESS2
POP ADDRESS1
RET
MULTIPLY ENDP
;------------------------------------------------
MOVERESULT PROC NEAR
PUSH ADDRESS1
PUSHA
MOV AX,[BP-2]
MOV ADDRESS1,AX
MOV CH,00H
MOV CL,LENTH
SHL CX,01H
DEC CX
MOV DI,ADDRESS1
A130:
INC SI
MOV AH,BYTE PTR [DI+1]
MOV BYTE PTR [DI],AH
INC DI
DEC CX
JNZ A130
MOV AH,00H
MOV BYTE PTR [DI],AH
POPA
POP ADDRESS1
RET
MOVERESULT ENDP
;------------------------------------------------
BIGER PROC NEAR
PUSH ADDRESS1
PUSH ADDRESS2
PUSH ADDRESS3
PUSHA
PUSHF
MOV AX,[BP-2]
MOV ADDRESS1,AX
MOV AX,[BP-4]
MOV ADDRESS2,AX
MOV AX,[BP-6]
MOV ADDRESS3,AX
MOV CH,00H
MOV CL,LENTH
MOV DI,ADDRESS1
MOV SI,ADDRESS2
A140:
MOV AH,[DI]
MOV AL,[SI]
CMP AH,AL
JNZ A150
INC DI
INC SI
DEC CX
JNZ A140
A150:
CMP AH,AL
JNBE A155 ;FLAG is set to 0000H before this function is called
MOV AX,1111H
MOV DI,ADDRESS3
MOV [DI],AX
A155:
POPF
POPA
POP ADDRESS3
POP ADDRESS2
POP ADDRESS1
RET
BIGER ENDP
;------------------------------------------------
SHLRESULT PROC NEAR
PUSH ADDRESS1
PUSHA
PUSHF
MOV AX,[BP-2]
MOV ADDRESS1,AX
MOV DI,ADDRESS1
MOV CH,00H
MOV CL,LENTH
SHL CX,01H
CLC
A160:
MOV BX,CX
MOV AL,[DI+BX-1]
RCL AL,01H
MOV [DI+BX-1],AL
DEC CX
JNZ A160
POPF
POPA
POP ADDRESS1
RET
SHLRESULT ENDP
;------------------------------------------------
END START
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -