⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mutdiv.asm.svn-base

📁 keilC底层软件,能够结合硬件产生加解密密文,具有安全保护功能.
💻 SVN-BASE
📖 第 1 页 / 共 4 页
字号:
;-------------------------------;
;*******************************;
;-------------------------------;
NAME    MUTDIV


PUBLIC _NMUL
PUBLIC _TaxCalc
PUBLIC _DebtCalc
PUBLIC _HouseCalc
PUBLIC _SavingCalc
PUBLIC _BCDADD
PUBLIC BCD_BIN_Pro
PUBLIC BIN_BCD_Pro
PUBLIC CalClear
PUBLIC Mul10
PUBLIC AddSum


PUBLIC	MUTDIV
extrn	xdata (TEMPSTART)
;------- 加减乘除及其子函数 begin --------


;-------------------
; _NDIV subroutines
;-------------------
;_NDIV
;YWCSQD
;BCS_RL1
;BCS_RL1A
;BCS_RLX
;CS_RLY
;BCS_RRR2
;SANADDONE
;DEC1TIME
;ADD1TIME
;-------------------
; _NMUL subroutines
;-------------------
;_NMUL
;CS_RR1
;LSCJ_RLB
;LSCJ_RL1
;BCSCOPY
;CLEAR_CJ
;CLEAR_LSCJ
;CalClear
;LSCJJZJ

;----------------------
;_MBIN_ADD subroutines
;----------------------
;----------------------
;_MBIN_SUB subroutines
;----------------------

;------- 加减乘除及其子函数 end --------


;----------------------
;_MBIN_COMP subroutines		;R7 (IN RAM)		R5 (IN RAM)
;----------------------
;----------------------
;_MBIN_COMPX subroutines	;R7 (IN RAM)		DPTR (EX RAM)
;----------------------
;DPTRADD
;----------------------
;ADDRPOINTER		EQU		07H
;MONEYIN			EQU		020H
;TAXNO				EQU		MONEYIN+4
;BIAOZUN			EQU		TAXNO+1

ALL_LENTH			EQU		04H
TWO_LENTH			EQU		ALL_LENTH+ALL_LENTH		;8
TWOLENADD1			EQU		TWO_LENTH+1			;9
FOUR_LENTH			EQU		TWO_LENTH+TWO_LENTH		;16
FOURLENADD1			EQU		FOUR_LENTH+1			;17

;FLASHBEGIN			EQU		0BB8H	;LENGTH=81 + 45 = 126 BYTES
;DEBTBEGIN			EQU		0C36H	;LENGTH=4 BYTES
;HOUSEBEGIN			EQU		0C3AH	;LENGTH=4 BYTES
;SAVEBEGIN			EQU		0C3EH	;LENGTH=14 BYTES

FLASHBEGIN			EQU		10		;0bb8h  ;LENGTH=81 + 45 = 126 BYTES
DEBTBEGIN			EQU		FLASHBEGIN+0x7e		;0C36H	;LENGTH=4 BYTES
HOUSEBEGIN			EQU		DEBTBEGIN+4			;0C3AH	;LENGTH=4 BYTES
SAVEBEGIN			EQU		HOUSEBEGIN+4		;0C3EH	;LENGTH=14 BYTES






?CO?MUTDIV SEGMENT CODE
	RSEG  ?CO?MUTDIV

MUTDIV:

;---------------------------------
; 模块名:tax_calc	MAKE:yujinhe
; 功能:个人所得税的计算
;---------------------------------

_TaxCalc:
	MOV		A,R1

;;;;	MOV		a,#2FH		;??????????
	MOV		R4,A				;为可用内 RAM 之首地址,指向 -->TAXNO
	INC		A

	MOV		R7,A				;输入金额 BEGIN
	CLR		C
	ADDC	A,#ALL_LENTH
	MOV		R5,A				;标准 BEGIN
	MOV		R3,#ALL_LENTH
	LCALL	_MBIN_COMP			;输入金额与标准比较
	JC		TaxCalc300			;小于标准
	JZ		TaxCalc300			;等于标准
	MOV		R3,#ALL_LENTH		;R7,R5 NO CHANGE,SO NO NEED INPUT
	LCALL	_MBIN_SUB			;减去标准金额

	MOV		R6,#0				;R6 为搜索税表的指针,在找到之前不可被后面子程序改写 !!
TaxCalc005:
	MOV		A,R4				;为可用内 RAM 之首地址,指向 -->TAXNO
	INC		A
	MOV		R7,A				;输入金额 BEGIN
	MOV		R3,#ALL_LENTH		;R7 NO CHANGE, SO NO NEED INPUT
	LCALL	_SETDPTR			;赋予 税表首地址指针 DPTR
	LCALL	DPTRADD
	LCALL	_MBIN_COMPX			;(IN: R7,DPTR,R3) 输入金额与税表等级比较
	JC		TaxCalc010			;小于
	JZ		TaxCalc010			;等于
	INC		R6					;GO TO MATCH THE NEXT
	MOV		A,R4
	MOV		R0,A
	MOV		A,@R0
	JZ		TaxCalc200
	CJNE	R6,#4,TaxCalc005
	SJMP	TaxCalc010
TaxCalc200:
	CJNE	R6,#8,TaxCalc005
	SJMP	TaxCalc010
TaxCalc300:
	MOV		A,R4
	MOV		R0,A
	MOV		A,#8
	LCALL	CalClear		;IF <= BIAOZHUN, ALL CLEAR "0"
	RET

TaxCalc010:
	CLR		C
	MOV		A,R4
	ADDC	A,#5
	MOV		R0,A				;R0= 乘数 BEGIN(LOW)
	MOV		R1,A
	MOV		A,#ALL_LENTH
	LCALL	CalClear		;CLEAR 乘数 4 BYTES
	LCALL	_SETDPTR			;赋予 税表首地址指针 DPTR
	LCALL	DPTRADD
	MOV		B,#8
	LCALL	DPTRADD10			;POINTER TO 税率
	MOVX	A,@DPTR
	MOV		@R1,A				;取得税率放入乘数区

	MOV		A,R4
	INC		A
	MOV		R7,A				;被乘数
	CLR		C
	ADDC	A,#ALL_LENTH
	MOV		R5,A				;乘数
	MOV		R3,#ALL_LENTH
	LCALL	_NMUL

	CLR		C
	MOV		A,R4
	ADDC	A,#TWOLENADD1
	MOV		R7,A				;SOURCE (BIN CODE)  +9
	CLR		C
	ADDC	A,#TWO_LENTH
	MOV		R5,A				;DEST (BCD CODE)	+17
	MOV		A,#ALL_LENTH
	RL		A
	MOV		R3,A				;CHANGE LENGTH

	MOV		A,R6
	PUSH	ACC
	LCALL	BIN_BCD_Pro
	POP		ACC
	MOV		R6,A				;转 BCD 码结束

	mov	a,r7
	dec	a					;10000变为100
	mov	r3,a

	MOV		A,R4
	ADD	A,#(FOURLENADD1+1)			;除十进制100
	MOV		R7,A				;SOURCE (BCD CODE)  +19-1
	MOV		A,R4
	ADD	A,#TWOLENADD1
	MOV		R5,A				;DEST (BIN CODE)	+9
	
;	MOV		A,#ALL_LENTH
;	RL		A
;	MOV		R3,A				;R3= #ALL_LENTH*3-1 =CHANGE LENGTH

	MOV		A,R6
	PUSH	ACC
	MOV		A,R4
	PUSH	ACC
	LCALL	BCD_BIN_Pro
	POP		ACC
	MOV		R4,A
	POP		ACC
	MOV		R6,A				;转 BIN 码结束

GetSSKCS:						;取速算扣除数
	LCALL	_SETDPTR			;赋予 税表首地址指针 DPTR
	LCALL	DPTRADD				;R6 NO CHANGE, SO NO NEED INPUT
	MOV		B,#4
	LCALL	DPTRADD10			;POINTER TO 取速算扣除数
	
	CLR		C
	MOV		A,R4
	ADDC	A,#FOURLENADD1
	MOV		R0,A				;DEST (速算扣除数放入减数区)
	MOV		R3,#ALL_LENTH		;LENGTH
GetSSKCS20:
	MOVX	A,@DPTR
	MOV		@R0,A
	INC		R0
	INC		DPTR
	DJNZ	R3,GetSSKCS20

	CLR		C
	MOV		A,R4
	ADDC	A,#TWOLENADD1
	MOV		R7,A				;SOURCE (BIN CODE) +9
	CLR		C
	ADDC	A,#TWO_LENTH
	MOV		R5,A				;DEST (BCD CODE)   +17
	MOV		R3,#ALL_LENTH		;SUB LENGTH=#ALL_LENTH

	LCALL	_MBIN_COMP			;与速算扣除数比较大小				;-------------------- 2/14/2003 update -------------
	JNC		GetSSKCS22			;大于等于速算扣除数
	LJMP	TaxCalc300			;小于速算扣除数
GetSSKCS22:
	JNZ		GetSSKCS24			;大于速算扣除数
	LJMP	TaxCalc300			;等于速算扣除数
GetSSKCS24:
	MOV		R3,#ALL_LENTH										;-------------------- 2/14/2003 update -------------

	LCALL	_MBIN_SUB

	MOV		A,R4
	MOV		R5,A				;DEST
	CLR		C
	ADDC	A,#TWOLENADD1
	MOV		R7,A				;SOURCE
	MOV		R3,#ALL_LENTH		;MOV LENGTH=#ALL_LENTH
	LCALL	_MBIN_MOV
	RET



;-------------------------------;
;*******************************;
;-------------------------------;

;?PR?_NDIV?LOWLVL SEGMENT CODE
;PUBLIC _NDIV
;RSEG ?PR?_NDIV?LOWLVL

;-------------------------------;
;*******************************;
;-------------------------------;
;Description:   多字节 BIN 码除法
;	IN:	
;		R7==被除数起始地址(LOW)
;		R5==除数起始地址(LOW)
;		R3==Length 	(BYTES)
;		令被除数与除数等长,不足位在高位补零.
;	OUT:	
;		?==商的起始地址(LOW) LEN<=R3
;		?==余数的起始地址(LOW) LEN<=R3
;		A==除法益出标志. (A=0XFF, OVER; A=0, NOOVER)
;-------------------------------;

_NDIV:
	LCALL 	YWCSQD		; 判断除数是否为零 C=1 YES,C=0 NO
	JC 		NDIV120
	LCALL	BCS_RLX
	LCALL	CS_RLY		; OUT B AND R2
		CLR		C
		MOV		A,B			;B  为除数自 (最高位到第一个非零位之间) 之位数
		SUBB	A,R2		;R2 为被除数 (最高位到第一个非零位之间) 之位数
		MOV		R2,A		;R2 为两数之位数差。
	JC		NDIV105			;被除数小于除数,只计四舍五入
	JNZ		NDIV060			;被除数位数大于除数位数
	MOV		R2,#1			;被除数与除数位数相等,只移一位。
	SJMP	NDIV070
NDIV060:
	LCALL	BCS_RRR2
	INC	R2
NDIV070:
	LCALL	DEC1TIME
	JNC		NDIV080		;如够减商加一则继续循环.
	LCALL	ADD1TIME	;如不够减则先恢复原值,再继续循环
	SJMP	NDIV100
NDIV080:
	LCALL	SANADDONE
NDIV100:
	DJNZ	R2,NDIV085
NDIV105:
	CLR		C
	LCALL	BCS_RL1A	;不带商左移一位。
	LCALL	DEC1TIME	;四舍五入
	JNC		NDIV090		;如够减商加一.
	LCALL	ADD1TIME	;如不够减则恢复原值,
	SJMP	NDIV095
NDIV090:
	LCALL	SANADDONE
NDIV095:
	CLR		F0
	CLR 	A
	SJMP 	NDIV200
NDIV085:
	LCALL	BCS_RL1		;带商左移一位。
	SJMP	NDIV070
NDIV120:
	MOV 	A,#0xFF		;除法益出标志
NDIV200:
	RET

;-----------------------------
; IN: NO
;OUT: 
;	C=溢出标志	=1 OVER;
;-----------------------------
YWCSQD:
	MOV 	A,R3
	PUSH 	ACC
	CLR 	C
	MOV 	A,R5
	ADDC 	A,R3		;此处地址可能会溢出,注意 !
	MOV 	R0,A
YWCS_20:
	DEC 	R0
	MOV 	A,@R0
	JNZ		YWCS_50		;自最高位起找第一个非零字节为止
	DJNZ 	R3,YWCS_20
	SETB 	C			;如除数全为零,置除法溢出标志
	SJMP	YWCS_60
YWCS_50:
	CLR		C
YWCS_60:
	POP 	ACC
	MOV 	R3,A
	RET

;--------------------------
;  被除数循环左移 X 位
;	IN :NO
;	OUT: B 为移出的 BITS
;--------------------------
BCS_RL1:
		CLR		C
		MOV 	A,R7
		SUBB	A,R3
		MOV 	R0,A
		MOV		A,R3
		MOV		R1,A
		RL		A
		MOV		R3,A		;R3*2
BCS_RL10:
		MOV		A,@R0		;从最低位开始
		RLC		A
		MOV		@R0,A
		INC		R0
		DJNZ	R3,BCS_RL10
		MOV		A,R1
		MOV		R3,A
		RET

BCS_RL1A:
		MOV		A,R3
		MOV		R1,A
		MOV 	A,R7
		MOV 	R0,A
BCS_RL1B:
		MOV		A,@R0		;从最低位开始
		RLC		A
		MOV		@R0,A
		INC		R0
		DJNZ	R3,BCS_RL1B
		MOV		A,R1
		MOV		R3,A
		RET

BCS_RLX:
		MOV		A,R3
		RL		A
		RL		A
		RL		A
		MOV		R2,A		;B 计数的最大值 = R3 * 8  BITS
		MOV		B,#0
BCS_RL05:
		MOV 	A,R3
		MOV		R1,A		;PROTECT R3
		CLR		C
		MOV 	A,R7
		MOV 	R0,A
BCS_RLX10:
		MOV		A,@R0		;从最低位开始
		RLC		A
		MOV		@R0,A
		INC		R0
		DJNZ	R3,BCS_RLX10
		MOV		A,R1
		MOV		R3,A		;RESTORE R3
		JC		BCS_RL15	;C=1
		INC		B			;"0" COUNT
		MOV		A,R2
		SUBB	A,B
		JNC		BCS_RL05	;未超出预定位数则继续
		SJMP	BCS_RL17	;如超出,则被除数为全零"000000"
BCS_RL15:
		MOV		A,B			;PROTECT B(X)
		PUSH	ACC
		INC		B
BCS_RL15A:
		MOV 	A,R3
		MOV		R1,A		;PROTECT R3
BCS_RL16:
		DEC		R0
		MOV		A,@R0
		RRC		A
		MOV		@R0,A
		DJNZ	R3,BCS_RL16
		MOV		A,R1
		MOV		R3,A		;RESTORE R3
		DJNZ	B,BCS_RL18
		MOV		A,R1
		MOV		R3,A		;RESTORE R3
		POP		ACC
		MOV		B,A			;RESTORE B(X)
BCS_RL17:
		RET

BCS_RL18:
		MOV		A,R7
		ADD		A,R1		;R7+R1 MUST NO OVER, FOR (C MUST KEEP)
		MOV		R0,A
		SJMP	BCS_RL15A

		
;--------------------------
; *******移位次数确定*******
;  除数循环左移 Y 位
;	IN :B -> R2->X
;	OUT: B 为 Y 
;		 C=0 NORMAL C=1说明
;	除数大于被除数,商为 0
;--------------------------
CS_RLY:
		MOV		A,B
		MOV		R2,A		;PROTECT X
		MOV		B,#0
CS_RL05:
		MOV 	A,R3
		MOV		R1,A		;PROTECT R3
		CLR		C
		MOV 	A,R5
		MOV 	R0,A
CS_RL10:
		MOV		A,@R0		;从最低位开始
		RLC		A
		MOV		@R0,A
		INC		R0
		DJNZ	R3,CS_RL10
		MOV		A,R1
		MOV		R3,A		;RESTORE R3
		JC		CS_RL15		;C=1
		INC		B
		SJMP	CS_RL05
CS_RL15:
		MOV		A,B			;PROTECT B(Y)
		PUSH	ACC
		INC		B
CS_RL15A:
		MOV 	A,R3
		MOV		R1,A		;PROTECT R3
CS_RL16:
		DEC		R0
		MOV		A,@R0
		RRC		A
		MOV		@R0,A
		DJNZ	R3,CS_RL16
		MOV		A,R1
		MOV		R3,A		;RESTORE R3
		DJNZ	B,CS_RL18
		MOV		A,R1
		MOV		R3,A		;RESTORE R3
		POP		ACC
		MOV		B,A			;RESTORE B(Y)
		RET
CS_RL18:
		MOV		A,R5
		ADD		A,R1		;R7+R1 MUST NO OVER, FOR (C MUST KEEP)
		MOV		R0,A
		SJMP	CS_RL15A


;--------------------------
;  被除数循环右移 R2 位
;	IN :R2
;	OUT: NO
;--------------------------
BCS_RRR2:
		MOV 	A,R2
		PUSH	ACC
		MOV		A,R3
		MOV		R1,A
BCS_RRR20:
		MOV		A,R1
		RL		A
		MOV		R3,A		;R3*2

		MOV 	A,R7
		ADD		A,R1
		MOV 	R0,A
		CLR		C
BCS_RRR25:
		DEC		R0
		MOV		A,@R0		;从最高位开始
		RRC		A
		MOV		@R0,A
		DJNZ	R3,BCS_RRR25
		DJNZ	R2,BCS_RRR20

		MOV		A,R1
		MOV		R3,A

		POP		ACC
		MOV		R2,A
		RET



;--------------------------
;  商数加 1
;	IN :NO
;	OUT: NO
;--------------------------
SANADDONE:				;02-6-19 17:48
	CLR		C
	MOV		A,R7		;商加 1
	SUBB	A,R3
	MOV		R0,A
	MOV		A,@R0
	ADD		A,#1
	MOV		@R0,A
	JNC		SANADDONE50	;无进位
	INC		R0
	INC		@R0
SANADDONE50:
	RET

;--------------------------------
;  被除数减除数一次,结果送回到被除数
;  中暂时保存。
;	LENGTH = R3
;	IN :NO
;	OUT: C 溢出标志(=1 over)
;--------------------------------
DEC1TIME:
		MOV		A,R3
		PUSH	ACC
		MOV		A,R7
		MOV		R0,A		;被除数最低位
		MOV		A,R5
		MOV		R1,A		;除数最低位
		CLR		C
DEC1TIME10:
		MOV		A,@R0

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -