1、AVR乘除法子程序AVR乘除法子程序;* 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 ;* ;* DESCRIPTION ;* This Application Note lists subroutines for the following ;* Muli
2、ply/Divide applications. Routines are straight-line implementations ;* optimized for speed: ;* ;* 8 x 8 = 16 bit unsigned ;* 16 x 8 = 32 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 ;* ;*
3、 ;* mpy8u - 8x8 Bit Unsigned Multiplication ;* ;* Number of cycles :65 ;* 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. ;* ;* ;* Subroutin
4、e Register Variables .def mc8u =r16 ;multiplicand .def mp8u =r17 ;multiplier .def m8uL =r17 ;result Low byte .def m8uH =r18 ;result High byte .def cycle =r31 ;* Code mpy8u: ldi cycle,8 clr m8uH ;clear result High byte lsr mp8u ;shift multiplier m8u: brcc noad80 ;if carry set add m8uH,mc8u ; add mult
5、iplicand to result High byte noad80: ror m8uH ;shift right result High byte ror m8uL ;rotate right result L byte and multiplier dec cycle brne m8u ret ;* ;* 2字节乘法子程序 ;-16bit*16bit- aH.aL * bH.bL = result3.2.1.0 -;-或-16bit*8bit- aH.aL * bL = Result3.2.1 -;*.def aL =r16 ;multiplicand low byte /被乘数.def
6、 aH =r17 ;multiplicand high byte .def bL =r18 ;multiplier low byte /乘数.def bH =r19 ;multiplier high byte .def result0 =r18 ;result byte 0 (LSB) .def result1 =r19 ;result byte 1 .def result2 =r20 ;result byte 2 .def result3 =r21 ;result byte 3 (MSB) .def cycle =r31;* Code m16_8u: ldi cycle,8 ldi R19,
7、0 rjmp mBeginm16_16u:ldi cycle,16mBegin: clr result3 ;clear 2 highest bytes of result clr result2 lsr bH ;乘数/2 ror bL ;C-Rd.0 Rd.0-Rd.1 Rd.15-0m16_16u1: brcc noadd ;若Rd.0=1 /(if carry set) add result2,aL ; 被乘数低字节加到结果的2字节 adc result3,aH ; 被乘数高字节加到结果的3字节noadd: ror result3 ;shift right result byte 3 ro
8、r result2 ;rotate right result byte 2 ror result1 ;rotate result byte 1 and multiplier High ror result0 ;rotate result byte 0 and multiplier Low dec cyclebrne m16_16u1 ret ;* ;* ;* div8u - 8/8 Bit Unsigned Division ;* ;* This subroutine divides the two register variables dd8u (dividend) and ;* dv8u
9、(divisor). The result is placed in dres8u and the remainder in ;* drem8u. ;* ;* Number of words :94 + return;* Low registers used :1 (drem8u) ;* High registers used :2 (dres8u/dd8u,dv8u,cycle) ;* ;* ;* Subroutine Register Variables .def drem8u =r15 ;remainder .def dres8u =r16 ;result .def dd8u =r16
10、;dividend .def dv8u =r17 ;divisor .def cycle =r18 ;* Code * R16/R17=R16+R15 * div8u: clr drem8u ;clear remainder and carry ldi cycle,9 ;8+1d8u_0: rol dd8u ;shift left dividend dec cycle breq d8u_2 rol drem8u ;shift dividend into remainder sub drem8u,dv8u ;remainder = remainder - divisor brcc d8u_1 ;
11、if result negative add drem8u,dv8u ; restore remainder clc ; clear carry to be shifted into result rjmp d8u_0 ;else d8u_1: sec ; set carry to be shifted into result rjmp d8u_0d8u_2: ret ;* ;* ;* div8u - 8/8 Bit Unsigned Division ;* ;* This subroutine divides the two register variables dd8u (dividend
12、) 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 d
13、rem8u =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 n
14、egative 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 res
15、ult 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 ;i
16、f 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
17、_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 brc
18、c d8u_9 ;if result negative add drem8u,dv8u ; restore remainder clc ; clear carry to be shifted into result rjmp d8u_10 ;else d8u_9: sec ; set carry to be shifted into result d8u_10: rol dd8u ;shift left dividend rol drem8u ;shift dividend into remainder sub drem8u,dv8u ;remainder = remainder - divi
19、sor brcc d8u_11 ;if result negative add drem8u,dv8u ; restore remainder clc ; clear carry to be shifted into result rjmp d8u_12 ;else d8u_11: sec ; set carry to be shifted into result d8u_12: rol dd8u ;shift left dividend rol drem8u ;shift dividend into remainder sub drem8u,dv8u ;remainder = remaind
20、er - divisor brcc d8u_13 ;if result negative add drem8u,dv8u ; restore remainder clc ; clear carry to be shifted into result rjmp d8u_14 ;else d8u_13: sec ; set carry to be shifted into result d8u_14: rol dd8u ;shift left dividend rol drem8u ;shift dividend into remainder sub drem8u,dv8u ;remainder
21、= remainder - divisor brcc d8u_15 ;if result negative add drem8u,dv8u ; restore remainder clc ; clear carry to be shifted into result rjmp d8u_16 ;else d8u_15: sec ; set carry to be shifted into result d8u_16: rol dd8u ;shift left dividend ret ;-div16_8u-16/8 bit- R20R19/R18=R20R19+R17R16 -.def dres
22、16uL=r19.def dres16uH=r20 .def dd16uL =r19 .def dd16uH =r20 .def dv8u =r18 .def dcnt16u =r22.def drem16uL=r16 .def drem16uH=r17 div16_8u: clr drem16uL ;clear remainder Low byte sub drem16uH,drem16uH;clear remainder High byte and carry ldi dcnt16u,17 d16u_1: rol dd16uL ;shift left dividend rol dd16uH
23、 dec dcnt16u breq d16u_3 ;完成? 跳出 rol drem16uL ;shift dividend into remainder rol drem16uH sub drem16uL,dv8u ;remainder = remainder - divisor brcc d16u_2 ;if result negative add drem16uL,dv8u ; restore remainder clc ; clear carry to be shifted into result rjmp d16u_1 ;else d16u_2: sec rjmp d16u_1d16u
24、_3: ret ;-16bit/16bit-.def drem16uL=r14 .def drem16uH=r15 .def dres16uL=r16 .def dres16uH=r17 .def dd16uL =r16 .def dd16uH =r17 .def dv16uL =r18 .def dv16uH =r19 .def dcnt16u =r20;* Code div16u: clr drem16uL ;clear remainder Low byte sub drem16uH,drem16uH;clear remainder High byte and carry ldi dcnt
25、16u,17 d16u_1: rol dd16uL ;shift left dividend rol dd16uH dec dcnt16u breq d16u_3 ;完成? 跳出 rol drem16uL ;shift dividend into remainder rol drem16uH sub drem16uL,dv16uL ;remainder = remainder - divisor sbc drem16uH,dv16uH ; brcc d16u_2 ;if result negative add drem16uL,dv16uL ; restore remainder adc dr
26、em16uH,dv16uH clc ; clear carry to be shifted into result rjmp d16u_1 ;else d16u_2: sec rjmp d16u_1d16u_3: ret;* ;* ;* div16u - 16/16 Bit Unsigned Division ;* ;* This subroutine divides the two 16-bit numbers ;* dd8uH:dd8uL (dividend) and dv16uH:dv16uL (divisor). ;* The result is placed in dres16uH:
27、dres16uL and the remainder in ;* drem16uH:drem16uL. ;* ;* Number of words :196 + return ;* Number of cycles :148/173/196 (Min/Avg/Max) ;* Low registers used :2 (drem16uL,drem16uH) ;* High registers used :4 (dres16uL/dd16uL,dres16uH/dd16uH,dv16uL,dv16uH) ;* ;* ;* Subroutine Register Variables .def drem1
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1