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

📄 avr_200_b.asm

📁 Collected AVR assembler code samples to learn assembler. I use it in my classes.
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;**** A P P L I C A T I O N   N O T E   A V R 2 0 0 ************************
;*
;* Title:		Multiply and Divide Routines
;* Version:		1.1
;* Last updated:	97.07.04
;* Target:		AT90Sxxxx (All AVR Devices)
;*
;* Support E-mail:	avr@atmel.com
;* 

;* DESCRIPTION
;* This Application Note lists subroutines for the following
;* Muliply/Divide applications. Routines are straight-line implementations
;* optimized for speed:
;*
;*  8 x  8 = 16 bit unsigned
;* 16 x 16 = 32 bit unsigned
;*  8 /  8 =  8 +  8 bit unsigned
;* 16 / 16 = 16 + 16 bit unsigned
;*

;***************************************************************************


.include "1200def.inc"

	rjmp	RESET	;reset handle

;***************************************************************************
;*
;* "mpy8u" - 8x8 Bit Unsigned Multiplication
;*
;* This subroutine multiplies the two register variables mp8u and mc8u.
;* The result is placed in registers m8uH, m8uL
;*  
;* Number of words	:34 + return
;* Number of cycles	:34 + return
;* Low registers used	:None
;* High registers used  :3 (mc8u,mp8u/m8uL,m8uH)	
;*
;* Note: Result Low byte and the multiplier share the same register.
;* This causes the multiplier to be overwritten by the result.
;*
;***************************************************************************

;***** Subroutine Register Variables

.def	mc8u	=r16		;multiplicand
.def	mp8u	=r17		;multiplier
.def	m8uL	=r17		;result Low byte
.def	m8uH	=r18		;result High byte

;***** Code

mpy8u:	clr	m8uH		;clear result High byte
	lsr	mp8u		;shift multiplier
	
	brcc	noad80		;if carry set
	add	m8uH,mc8u	;    add multiplicand to result High byte
noad80:	ror	m8uH		;shift right result High byte 
	ror	m8uL		;rotate right result L byte and multiplier

	brcc	noad81		;if carry set
	add	m8uH,mc8u	;    add multiplicand to result High byte
noad81:	ror	m8uH		;shift right result High byte 
	ror	m8uL		;rotate right result L byte and multiplier

	brcc	noad82		;if carry set
	add	m8uH,mc8u	;    add multiplicand to result High byte
noad82:	ror	m8uH		;shift right result High byte 
	ror	m8uL		;rotate right result L byte and multiplier

	brcc	noad83		;if carry set
	add	m8uH,mc8u	;    add multiplicand to result High byte
noad83:	ror	m8uH		;shift right result High byte 
	ror	m8uL		;rotate right result L byte and multiplier

	brcc	noad84		;if carry set
	add	m8uH,mc8u	;    add multiplicand to result High byte
noad84:	ror	m8uH		;shift right result High byte 
	ror	m8uL		;rotate right result L byte and multiplier

	brcc	noad85		;if carry set
	add	m8uH,mc8u	;    add multiplicand to result High byte
noad85:	ror	m8uH		;shift right result High byte 
	ror	m8uL		;rotate right result L byte and multiplier

	brcc	noad86		;if carry set
	add	m8uH,mc8u	;    add multiplicand to result High byte
noad86:	ror	m8uH		;shift right result High byte 
	ror	m8uL		;rotate right result L byte and multiplier

	brcc	noad87		;if carry set
	add	m8uH,mc8u	;    add multiplicand to result High byte
noad87:	ror	m8uH		;shift right result High byte 
	ror	m8uL		;rotate right result L byte and multiplier
	
	ret


;***************************************************************************
;*
;* "mpy16u" - 16x16 Bit Unsigned Multiplication
;*
;* This subroutine multiplies the two 16-bit register variables 
;* mp16uH:mp16uL and mc16uH:mc16uL.
;* The result is placed in m16u3:m16u2:m16u1:m16u0.
;*  
;* Number of words	:105 + return
;* Number of cycles	:105 + return
;* Low registers used	:None
;* High registers used  :6 (mp16uL,mp16uH,mc16uL/m16u0,mc16uH/m16u1,m16u2,
;*			    m16u3)	
;*
;***************************************************************************

;***** Subroutine Register Variables



.def	mc16uL	=r16		;multiplicand low byte
.def	mc16uH	=r17		;multiplicand high byte
.def	mp16uL	=r18		;multiplier low byte
.def	mp16uH	=r19		;multiplier high byte
.def	m16u0	=r18		;result byte 0 (LSB)
.def	m16u1	=r19		;result byte 1
.def	m16u2	=r20		;result byte 2
.def	m16u3	=r21		;result byte 3 (MSB)

;***** Code

mpy16u:	clr	m16u3		;clear 2 highest bytes of result
	clr	m16u2	
	lsr	mp16uH		;rotate multiplier Low
	ror	mp16uL		;rotate multiplier High

	brcc	noadd0		;if carry set
	add	m16u2,mc16uL	;    add multiplicand Low to byte 2 of res
	adc	m16u3,mc16uH	;    add multiplicand high to byte 3 of res
noadd0:	ror	m16u3		;shift right result byte 3
	ror	m16u2		;rotate right result byte 2
	ror	m16u1		;rotate result byte 1 and multiplier High
	ror	m16u0		;rotate result byte 0 and multiplier Low

	brcc	noadd1		;if carry set
	add	m16u2,mc16uL	;    add multiplicand Low to byte 2 of res
	adc	m16u3,mc16uH	;    add multiplicand high to byte 3 of res
noadd1:	ror	m16u3		;shift right result byte 3
	ror	m16u2		;rotate right result byte 2
	ror	m16u1		;rotate result byte 1 and multiplier High
	ror	m16u0		;rotate result byte 0 and multiplier Low

	brcc	noadd2		;if carry set
	add	m16u2,mc16uL	;    add multiplicand Low to byte 2 of res
	adc	m16u3,mc16uH	;    add multiplicand high to byte 3 of res
noadd2:	ror	m16u3		;shift right result byte 3
	ror	m16u2		;rotate right result byte 2
	ror	m16u1		;rotate result byte 1 and multiplier High
	ror	m16u0		;rotate result byte 0 and multiplier Low

	brcc	noadd3		;if carry set
	add	m16u2,mc16uL	;    add multiplicand Low to byte 2 of res
	adc	m16u3,mc16uH	;    add multiplicand high to byte 3 of res
noadd3:	ror	m16u3		;shift right result byte 3
	ror	m16u2		;rotate right result byte 2
	ror	m16u1		;rotate result byte 1 and multiplier High
	ror	m16u0		;rotate result byte 0 and multiplier Low

	brcc	noadd4		;if carry set
	add	m16u2,mc16uL	;    add multiplicand Low to byte 2 of res
	adc	m16u3,mc16uH	;    add multiplicand high to byte 3 of res
noadd4:	ror	m16u3		;shift right result byte 3
	ror	m16u2		;rotate right result byte 2
	ror	m16u1		;rotate result byte 1 and multiplier High
	ror	m16u0		;rotate result byte 0 and multiplier Low

	brcc	noadd5		;if carry set
	add	m16u2,mc16uL	;    add multiplicand Low to byte 2 of res
	adc	m16u3,mc16uH	;    add multiplicand high to byte 3 of res
noadd5:	ror	m16u3		;shift right result byte 3
	ror	m16u2		;rotate right result byte 2
	ror	m16u1		;rotate result byte 1 and multiplier High
	ror	m16u0		;rotate result byte 0 and multiplier Low

	brcc	noadd6		;if carry set
	add	m16u2,mc16uL	;    add multiplicand Low to byte 2 of res
	adc	m16u3,mc16uH	;    add multiplicand high to byte 3 of res
noadd6:	ror	m16u3		;shift right result byte 3
	ror	m16u2		;rotate right result byte 2
	ror	m16u1		;rotate result byte 1 and multiplier High
	ror	m16u0		;rotate result byte 0 and multiplier Low

	brcc	noadd7		;if carry sett
	add	m16u2,mc16uL	;    add multiplicand Low to byte 2 of res
	adc	m16u3,mc16uH	;    add multiplicand high to byte 3 of res
noadd7:	ror	m16u3		;shift right result byte 3
	ror	m16u2		;rotate right result byte 2
	ror	m16u1		;rotate result byte 1 and multiplier High
	ror	m16u0		;rotate result byte 0 and multiplier Low

	brcc	noadd8		;if carry set
	add	m16u2,mc16uL	;    add multiplicand Low to byte 2 of res
	adc	m16u3,mc16uH	;    add multiplicand high to byte 3 of res
noadd8:	ror	m16u3		;shift right result byte 3
	ror	m16u2		;rotate right result byte 2
	ror	m16u1		;rotate result byte 1 and multiplier High
	ror	m16u0		;rotate result byte 0 and multiplier Low

	brcc	noadd9		;if carry set
	add	m16u2,mc16uL	;    add multiplicand Low to byte 2 of res
	adc	m16u3,mc16uH	;    add multiplicand high to byte 3 of res
noadd9:	ror	m16u3		;shift right result byte 3
	ror	m16u2		;rotate right result byte 2
	ror	m16u1		;rotate result byte 1 and multiplier High
	ror	m16u0		;rotate result byte 0 and multiplier Low

	brcc	noad10		;if carry set
	add	m16u2,mc16uL	;    add multiplicand Low to byte 2 of res
	adc	m16u3,mc16uH	;    add multiplicand high to byte 3 of res
noad10:	ror	m16u3		;shift right result byte 3
	ror	m16u2		;rotate right result byte 2
	ror	m16u1		;rotate result byte 1 and multiplier High
	ror	m16u0		;rotate result byte 0 and multiplier Low

	brcc	noad11		;if carry set
	add	m16u2,mc16uL	;    add multiplicand Low to byte 2 of res
	adc	m16u3,mc16uH	;    add multiplicand high to byte 3 of res
noad11:	ror	m16u3		;shift right result byte 3
	ror	m16u2		;rotate right result byte 2
	ror	m16u1		;rotate result byte 1 and multiplier High
	ror	m16u0		;rotate result byte 0 and multiplier Low

	brcc	noad12		;if carry set
	add	m16u2,mc16uL	;    add multiplicand Low to byte 2 of res
	adc	m16u3,mc16uH	;    add multiplicand high to byte 3 of res
noad12:	ror	m16u3		;shift right result byte 3
	ror	m16u2		;rotate right result byte 2
	ror	m16u1		;rotate result byte 1 and multiplier High
	ror	m16u0		;rotate result byte 0 and multiplier Low

	brcc	noad13		;if carry set
	add	m16u2,mc16uL	;    add multiplicand Low to byte 2 of res
	adc	m16u3,mc16uH	;    add multiplicand high to byte 3 of res
noad13:	ror	m16u3		;shift right result byte 3
	ror	m16u2		;rotate right result byte 2
	ror	m16u1		;rotate result byte 1 and multiplier High
	ror	m16u0		;rotate result byte 0 and multiplier Low

	brcc	noad14		;if carry set
	add	m16u2,mc16uL	;    add multiplicand Low to byte 2 of res
	adc	m16u3,mc16uH	;    add multiplicand high to byte 3 of res
noad14:	ror	m16u3		;shift right result byte 3
	ror	m16u2		;rotate right result byte 2
	ror	m16u1		;rotate result byte 1 and multiplier High
	ror	m16u0		;rotate result byte 0 and multiplier Low

	brcc	noad15		;if carry set
	add	m16u2,mc16uL	;    add multiplicand Low to byte 2 of res
	adc	m16u3,mc16uH	;    add multiplicand high to byte 3 of res
noad15:	ror	m16u3		;shift right result byte 3
	ror	m16u2		;rotate right result byte 2
	ror	m16u1		;rotate result byte 1 and multiplier High
	ror	m16u0		;rotate result byte 0 and multiplier Low

	ret



;***************************************************************************
;*
;* "div8u" - 8/8 Bit Unsigned Division
;*
;* This subroutine divides the two register variables "dd8u" (dividend) and 
;* "dv8u" (divisor). The result is placed in "dres8u" and the remainder in
;* "drem8u".
;*  
;* Number of words	:66 + return
;* Number of cycles	:50/58/66 (Min/Avg/Max) + return
;* Low registers used	:1 (drem8u)
;* High registers used  :2 (dres8u/dd8u,dv8u)
;*
;***************************************************************************

;***** Subroutine Register Variables

.def	drem8u	=r15		;remainder
.def	dres8u	=r16		;result
.def	dd8u	=r16		;dividend
.def	dv8u	=r17		;divisor

;***** Code

div8u:	sub	drem8u,drem8u	;clear remainder and carry
	
	rol	dd8u		;shift left dividend
	rol	drem8u		;shift dividend into remainder
	sub	drem8u,dv8u	;remainder = remainder - divisor
	brcc	d8u_1		;if result negative
	add	drem8u,dv8u	;    restore remainder
	clc			;    clear carry to be shifted into result
	rjmp	d8u_2		;else
d8u_1:	sec			;    set carry to be shifted into result

d8u_2:	rol	dd8u		;shift left dividend
	rol	drem8u		;shift dividend into remainder
	sub	drem8u,dv8u	;remainder = remainder - divisor
	brcc	d8u_3		;if result negative
	add	drem8u,dv8u	;    restore remainder
	clc			;    clear carry to be shifted into result
	rjmp	d8u_4		;else
d8u_3:	sec			;    set carry to be shifted into result

d8u_4:	rol	dd8u		;shift left dividend
	rol	drem8u		;shift dividend into remainder
	sub	drem8u,dv8u	;remainder = remainder - divisor
	brcc	d8u_5		;if result negative
	add	drem8u,dv8u	;    restore remainder
	clc			;    clear carry to be shifted into result
	rjmp	d8u_6		;else
d8u_5:	sec			;    set carry to be shifted into result

d8u_6:	rol	dd8u		;shift left dividend
	rol	drem8u		;shift dividend into remainder
	sub	drem8u,dv8u	;remainder = remainder - divisor
	brcc	d8u_7		;if result negative
	add	drem8u,dv8u	;    restore remainder
	clc			;    clear carry to be shifted into result
	rjmp	d8u_8		;else
d8u_7:	sec			;    set carry to be shifted into result

d8u_8:	rol	dd8u		;shift left dividend
	rol	drem8u		;shift dividend into remainder
	sub	drem8u,dv8u	;remainder = remainder - divisor
	brcc	d8u_9		;if result negative
	add	drem8u,dv8u	;    restore remainder
	clc			;    clear carry to be shifted into result

⌨️ 快捷键说明

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