calculator.asm
来自「基于Multisim9的电子系统设计、仿真与综合应用(实例源文件)」· 汇编 代码 · 共 974 行 · 第 1/2 页
ASM
974 行
checknum13:
CJNE A, #0DH,checknum14
MOV A, #09H
JMP numfound
checknum14:
CJNE A, #0EH,checknum15
MOV A, #08H
JMP numfound
checknum15:
CJNE A, #0FH, checkclear
MOV A, #07H
JMP numfound
checkclear:
CJNE A, #03H, checkplus
JMP cleardisplay
checkplus:
CJNE A, #0CH, checkminus
JMP operatorfound
checkminus:
CJNE A, #08H, checkmultiply
JMP operatorfound
checkmultiply:
CJNE A, #04H, checkdivide
JMP operatorfound
checkdivide:
CJNE A, #00H, checkequalop
JMP operatorfound
checkequalop:
CJNE A, #01H, numnotfound
JMP equalfound
equalfound:
MOV R1, #02H
MOV R7, A
JMP displaynumend
operatorfound:
MOV R1, #00H
MOV R7, A
JMP displaynumend
numnotfound:
MOV R7, #0FFH
JMP displaynumend
numfound:
MOV R1, #01H
MOV R7, A
; convert hex to dec
CALL HEXtoDEC
; Shift number to the left before displaying
call shiftnumleft
; display decimal numbers
MOV A, R5
MOV P2, A
MOV A, R6
MOV P0, A
call delay
;convert decimal to hex and store
CALL DECtoHEX
displaynumend:
RET
; R7 contains the new value
; R5 and R6 contains low and high byte of number to be shifted
shiftnumleft:
PUSH ACC
shiftnumleftstart:
MOV A, R7
PUSH ACC
MOV A, R6
MOV R7, #004H
checkhighnumloop:
RLC A
JC noshift
DJNZ R7, checkhighnumloop
JMP doshift
noshift:
POP ACC
MOV R7, A
JMP shiftnumleftend
doshift:
POP ACC
SWAP A
MOV R7, #004H
shiftbitleft:
RLC A
PUSH ACC
; Take carry bit and rotate it into R5
MOV A, R5
RLC A
MOV R5, A
MOV A, R6
RLC A
MOV R6, A
POP ACC
DJNZ R7, shiftbitleft
shiftnumleftend:
POP ACC
RET
cleardisplay:
MOV R5, #00H
MOV A, R5
MOV P2, A
MOV R6, #00H
MOV A, R6
MOV P0, A
CALL delay
MOV R1, #03H
JMP displaynumend
; Wait for no key press
lineclear:
MOV P1, #0FFH
lineclearloop:
MOV A, P1
XRL A, #0FFH
JNZ lineclearloop
RET
delay:
JB EWB.0,delayend ; Jump if using EWB Trace Mode
PUSH ACC
MOV A, R5
PUSH ACC
MOV A, R6
PUSH ACC
MOV R5, #50 ; number of innerdelay's to call
CLR A
outerdelay:
MOV R6, A
CALL innerdelay
DJNZ R5, outerdelay
POP ACC
MOV R6, A
POP ACC
MOV R5, A
POP ACC
delayend:
RET
innerdelay:
NOP
NOP
NOP
NOP
NOP
DJNZ R6, innerdelay
RET
; 16-bit signed (2's complement) addition
; INPUT:
; R3, R2 = X
; R1, R0 = Y
; OUTPUT:
; R1, R0 = SUM S = X+Y
; Carry C is set if S is out of range
ADD16:
PUSH ACC
MOV A, R0
ADD A, R2
MOV R0, A
MOV A, R1
ADDC A, R3
MOV R1, A
MOV C, OV
POP ACC
RET
; 16- bit signed (2's complement) subtraction
; INPUT:
; R1, R0 = X
; R3, R2 = Y
; OUTPUT:
; R1, R0 = signed difference D = X-Y
; Carry C is set if the result D is out of range
SUB16:
PUSH ACC
MOV A, R0
CLR C
SUBB A, R2
MOV R0, A
MOV A, R1
SUBB A, R3
MOV R1, A
MOV C, OV
POP ACC
RET
; 16-bit x 16-bit to 32-bit product unsigned mulitply
; INPUT:
; R1, R0 = X
; R3, R2 = Y
; OUTPUT:
; R3, R2, R1, R0 = product P = X*Y
UMUL16:
PUSH ACC
PUSH B
PUSH DPL
MOV A, R0
MOV B, R2
MUL AB ; multiply XL and YL
PUSH ACC ; stack result low byte
PUSH B ; stack result high byte
MOV A, R0
MOV B, R3
MUL AB ; multiply XL and YH
MOV R0, A
POP ACC
ADD A, R0
MOV R0, A
CLR A
ADDC A, B
MOV DPL, A
MOV A, R2
MOV B, R1
MUL AB ; multiply XH and YL
ADD A, R0
MOV R0, A
MOV A, DPL
ADDC A, B
MOV DPL, A
CLR A
ADDC A, #00H
PUSH ACC ; save intermediate carry
MOV A, R3
MOV B, R1
MUL AB ; multiply XH and YH
ADD A, DPL
MOV R2, A
POP ACC ; retrieve carry
ADDC A, B
MOV R3, A
MOV A, R0
MOV R1, A
POP ACC ; retrieve result low byte
MOV R0, A
POP DPL
POP B
POP ACC
RET
; 16-bit / 16-bit to 16-bit quotient and remainder unsigned divide
; Input:
; R1, R0 = Dividend X
; R3, R2 = Divisor Y
; Output:
; R1, R0 = quotient Q of division Q = X/Y
; R3, R2 = remainder
; alters: acc, B, dpl, dph, r4, r5, r6, r7
UDIV16:
PUSH ACC
MOV A, R4
PUSH ACC
MOV A, R5
PUSH ACC
MOV A, R6
PUSH ACC
MOV A, R7
PUSH ACC
MOV R7, #0H ; clear partial remainder
MOV R6, #0H
MOV B, #016 ; set loop count
DIV_LOOP:
CLR C ; clear carry flag
MOV A, R0 ; shift the highest bit of
RLC A ; the dividend into...
MOV R0, A
MOV A, R1
RLC A
MOV R1, A
MOV A, R6 ; the lowest bit of the
RLC A ; partial remainder
MOV R6, A
MOV A, R7
RLC A
MOV R7, A
MOV A, R6 ; trial subtract divisor
CLR C ; from partial remainder
SUBB A, R2
MOV DPL, A
MOV A, R7
SUBB A, R3
MOV DPH, A
CPL C ; complement external borrow
JNC DIV_1 ; update partial remainder if borrow
MOV R7, DPH ; update partial remainder
MOV R6, DPL
DIV_1:
MOV A, R4 ; shift result bit into partial
RLC A ; quotient
MOV R4, A
MOV A, R5
RLC A
MOV R5, A
DJNZ B, DIV_LOOP
MOV A, R5 ; put quotient in R0 and R1
MOV R1, A
MOV A, R4
MOV R0, A
MOV A, R7 ; get remainder, saved before the
MOV R3, A ; last subtraction
MOV A, R6
MOV R2, A
POP ACC
MOV R7, A
POP ACC
MOV R6, A
POP ACC
MOV R5, A
POP ACC
MOV R4, A
POP ACC
RET
; Conversion from base 10 to hexadecimal number
; Input:
; R5 - low byte of decimal value, R6 - high byte of decimal value
; Output:
; R5 - low byte of hex value, R6 - high byte of hex value
DECtoHEX:
PUSH ACC
MOV A, R0
PUSH ACC
MOV A, R1
PUSH ACC
MOV A, R2
PUSH ACC
MOV A, R3
PUSH ACC
MOV A, R4
PUSH ACC
MOV A, R5
ANL A, #0FH
MOV R3, A
MOV A, R5
SWAP A
ANL A, #0FH
MOV B, #0AH
MUL AB
ADD A, R3
MOV R3, A
MOV A, B
MOV R4, #0H
ADDC A, R4
MOV R4, A
MOV A, R6
ANL A, #0FH
MOV B, #064H
MUL AB
MOV R0, A
MOV R1, B
MOV A, R3
MOV R2, A
MOV A, R4
MOV R3, A
CALL ADD16
MOV A, R0
MOV R3, A
MOV A, R1
MOV R4, A
MOV A, R6
SWAP A
ANL A, #0FH
MOV R0, A
MOV R1, #00H
MOV R2, #0E8H
MOV A, R3 ; save R3 value
PUSH ACC
MOV R3, #03H
CALL UMUL16 ; result should never be greater than 270FH
POP ACC ; retrieve original value of R3
MOV R2, A
MOV A, R4
MOV R3, A
CALL ADD16
MOV A, R0
MOV R5, A
MOV A, R1
MOV R6, A
POP ACC
MOV R4, A
POP ACC
MOV R3, A
POP ACC
MOV R2, A
POP ACC
MOV R1, A
POP ACC
MOV R0, A
POP ACC
RET
; Conversion from hexadecimal to base 10 value
; Input:
; R5 - low byte of hex value, R6 - high byte of hex value
; Output:
; R5 - low byte of decimal value, R6 - high byte of decimal value
HEXtoDEC:
PUSH ACC
MOV A, R0
PUSH ACC
MOV A, R1
PUSH ACC
MOV A, R2
PUSH ACC
MOV A, R3
PUSH ACC
MOV A, R4
PUSH ACC
MOV A, R5 ; set up dividend
MOV R0, A
MOV A, R6
MOV R1, A
MOV R3, #0H ; set up divisor
MOV R2, #0AH
CALL UDIV16
MOV A, R2
MOV R5, A
MOV R6, #0H
MOV R2, #0AH
MOV R3, #0H
CALL UDIV16
MOV A, R5
SWAP A
ADD A, R2
SWAP A
MOV R5, A
MOV R2, #0AH
MOV R3, #0H
CALL UDIV16
MOV A, R2
SWAP A
ADD A, R0
SWAP A
MOV R6, A
POP ACC
MOV R4, A
POP ACC
MOV R3, A
POP ACC
MOV R2, A
POP ACC
MOV R1, A
POP ACC
MOV R0, A
POP ACC
RET
END
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?