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 + -
显示快捷键?