《AVR乘除法子程序.doc》由会员分享,可在线阅读,更多相关《AVR乘除法子程序.doc(38页珍藏版)》请在得力文库 - 分享文档赚钱的网站上搜索。
1、优质文本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: ;* ;* DESCRIPTION ;* This Application Note lists subroutines for the following ;* Muliply/Divide ap
2、plications. 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 rjmpRESET;reset handle ;* ;* ;* mpy8u - 8x8
3、 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. ;* ;* ;* Subroutine Register Variab
4、les .defmc8u=r16;multiplicand .defmp8u=r17;multiplier .defm8uL=r17;result Low byte .defm8uH=r18;result High byte .defcycle=r31;* Code mpy8u: ldi cycle,8clrm8uH;clear result High byte lsrmp8u;shift multiplier m8u: brccnoad80;if carry set addm8uH,mc8u; add multiplicand to result High byte noad80:rorm8
5、uH;shift right result High byte rorm8uL;rotate right result L byte and multiplier dec cyclebrne m8uret ;* ;* 2字节乘法子程序 ;-16bit*16bit- aH.aL * bH.bL = result3.2.1.0 -;-或-16bit*8bit- aH.aL * bL = Result3.2.1 -;*.defaL=r16;multiplicand low byte /被乘数.defaH=r17;multiplicand high byte .defbL=r18;multiplier
6、 low byte /乘数.defbH=r19;multiplier high byte .defresult0=r18;result byte 0 (LSB) .defresult1=r19;result byte 1 .defresult2=r20;result byte 2 .defresult3=r21;result byte 3 (MSB) .defcycle=r31;* Code m16_8u: ldi cycle,8ldi R19,0rjmp mBeginm16_16u:ldi cycle,16mBegin:clrresult3;clear 2 highest bytes of
7、result clrresult2 lsrbH;乘数/2rorbL;C-Rd.0 Rd.0-Rd.1 Rd.15-0m16_16u1:brccnoadd;假设Rd.0=1/(if carry set)addresult2,aL; 被乘数低字节加到结果的2字节 adcresult3,aH; 被乘数高字节加到结果的3字节noadd:rorresult3;shift right result byte 3 rorresult2;rotate right result byte 2 rorresult1;rotate result byte 1 and multiplier High rorresul
8、t0;rotate result byte 0 and multiplier Low dec cyclebrne m16_16u1ret ;* ;* ;* 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:94 + re
9、turn;* Low registers used:1 (drem8u) ;* High registers used :2 (dres8u/dd8u,dv8u,cycle) ;* ;* ;* Subroutine Register Variables .defdrem8u=r15;remainder .defdres8u=r16;result .defdd8u=r16;dividend .defdv8u=r17;divisor .defcycle=r18;* Code * R16/R17=R16+R15 *div8u:clrdrem8u;clear remainder and carry l
10、di cycle,9;8+1d8u_0: roldd8u;shift left dividenddec cyclebreqd8u_2roldrem8u;shift dividend into remainder subdrem8u,dv8u;remainder = remainder - divisor brccd8u_1;if result negative adddrem8u,dv8u; restore remainder clc; clear carry to be shifted into result rjmpd8u_0;else d8u_1:sec; set carry to be
11、 shifted into resultrjmpd8u_0d8u_2: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
12、/66 (Min/Avg/Max) + return ;* Low registers used:1 (drem8u) ;* High registers used :2 (dres8u/dd8u,dv8u) ;* ;* ;* Subroutine Register Variables .defdrem8u=r15;remainder .defdres8u=r16;result .defdd8u=r16;dividend .defdv8u=r17;divisor ;* Code div8u:subdrem8u,drem8u;clear remainder and carry roldd8u;s
13、hift left dividend roldrem8u;shift dividend into remainder subdrem8u,dv8u;remainder = remainder - divisor brccd8u_1;if result negative adddrem8u,dv8u; restore remainder clc; clear carry to be shifted into result rjmpd8u_2;else d8u_1:sec; set carry to be shifted into result d8u_2:roldd8u;shift left d
14、ividend roldrem8u;shift dividend into remainder subdrem8u,dv8u;remainder = remainder - divisor brccd8u_3;if result negative adddrem8u,dv8u; restore remainder clc; clear carry to be shifted into result rjmpd8u_4;else d8u_3:sec; set carry to be shifted into result d8u_4:roldd8u;shift left dividend rol
15、drem8u;shift dividend into remainder subdrem8u,dv8u;remainder = remainder - divisor brccd8u_5;if result negative adddrem8u,dv8u; restore remainder clc; clear carry to be shifted into result rjmpd8u_6;else d8u_5:sec; set carry to be shifted into result d8u_6:roldd8u;shift left dividend roldrem8u;shif
16、t dividend into remainder subdrem8u,dv8u;remainder = remainder - divisor brccd8u_7;if result negative adddrem8u,dv8u; restore remainder clc; clear carry to be shifted into result rjmpd8u_8;else d8u_7:sec; set carry to be shifted into result d8u_8:roldd8u;shift left dividend roldrem8u;shift dividend
17、into remainder subdrem8u,dv8u;remainder = remainder - divisor brccd8u_9;if result negative adddrem8u,dv8u; restore remainder clc; clear carry to be shifted into result rjmpd8u_10;else d8u_9:sec; set carry to be shifted into result d8u_10:roldd8u;shift left dividend roldrem8u;shift dividend into rema
18、inder subdrem8u,dv8u;remainder = remainder - divisor brccd8u_11;if result negative adddrem8u,dv8u; restore remainder clc; clear carry to be shifted into result rjmpd8u_12;else d8u_11:sec; set carry to be shifted into result d8u_12:roldd8u;shift left dividend roldrem8u;shift dividend into remainder s
19、ubdrem8u,dv8u;remainder = remainder - divisor brccd8u_13;if result negative adddrem8u,dv8u; restore remainder clc; clear carry to be shifted into result rjmpd8u_14;else d8u_13:sec; set carry to be shifted into result d8u_14:roldd8u;shift left dividend roldrem8u;shift dividend into remainder subdrem8
20、u,dv8u;remainder = remainder - divisor brccd8u_15;if result negative adddrem8u,dv8u; restore remainder clc; clear carry to be shifted into result rjmpd8u_16;else d8u_15:sec; set carry to be shifted into result d8u_16:roldd8u;shift left dividend ret ;-div16_8u-16/8 bit- R20R19/R18=R20R19+R17R16 -.def
21、dres16uL=r19.defdres16uH=r20 .defdd16uL=r19 .defdd16uH=r20 .defdv8u=r18 .defdcnt16u=r22.defdrem16uL=r16 .defdrem16uH=r17div16_8u:clrdrem16uL;clear remainder Low byte subdrem16uH,drem16uH;clear remainder High byte and carry ldi dcnt16u,17 d16u_1:roldd16uL;shift left dividend roldd16uH dec dcnt16ubreq
22、d16u_3;完成? 跳出roldrem16uL;shift dividend into remainder roldrem16uH subdrem16uL,dv8u;remainder = remainder - divisor brccd16u_2;if result negative adddrem16uL,dv8u; restore remainder clc; clear carry to be shifted into result rjmpd16u_1;else d16u_2:secrjmpd16u_1d16u_3:ret;-16bit/16bit-.defdrem16uL=r1
23、4 .defdrem16uH=r15 .defdres16uL=r16 .defdres16uH=r17 .defdd16uL=r16 .defdd16uH=r17 .defdv16uL=r18 .defdv16uH=r19 .defdcnt16u=r20;* Code div16u:clrdrem16uL;clear remainder Low byte subdrem16uH,drem16uH;clear remainder High byte and carry ldi dcnt16u,17 d16u_1:roldd16uL;shift left dividend roldd16uH d
24、ec dcnt16ubreqd16u_3;完成? 跳出roldrem16uL;shift dividend into remainder roldrem16uH subdrem16uL,dv16uL;remainder = remainder - divisor sbcdrem16uH,dv16uH; brccd16u_2;if result negative adddrem16uL,dv16uL; restore remainder adcdrem16uH,dv16uH clc; clear carry to be shifted into result rjmpd16u_1;else d1
25、6u_2:secrjmpd16u_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:dres16uL and the remainder in ;* drem16uH:drem16uL. ;* ;* Number of words:196 + re
26、turn ;* 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 .defdrem16uL=r14 .defdrem16uH=r15 .defdres16uL=r16 .defdres16uH=r17 .defdd16uL=r16 .defdd16u
27、H=r17 .defdv16uL=r18 .defdv16uH=r19 ;* Code div16u:clrdrem16uL;clear remainder Low byte subdrem16uH,drem16uH;clear remainder High byte and carry roldd16uL;shift left dividend roldd16uH roldrem16uL;shift dividend into remainder roldrem16uH subdrem16uL,dv16uL;remainder = remainder - divisor sbcdrem16u
28、H,dv16uH; brccd16u_1;if result negative adddrem16uL,dv16uL; restore remainder adcdrem16uH,dv16uH clc; clear carry to be shifted into result rjmpd16u_2;else d16u_1:sec; set carry to be shifted into result d16u_2:roldd16uL;shift left dividend roldd16uH roldrem16uL;shift dividend into remainder roldrem
29、16uH subdrem16uL,dv16uL;remainder = remainder - divisor sbcdrem16uH,dv16uH; brccd16u_3;if result negative adddrem16uL,dv16uL; restore remainder adcdrem16uH,dv16uH clc; clear carry to be shifted into result rjmpd16u_4;else d16u_3:sec; set carry to be shifted into result d16u_4:roldd16uL;shift left di
30、vidend roldd16uH roldrem16uL;shift dividend into remainder roldrem16uH subdrem16uL,dv16uL;remainder = remainder - divisor sbcdrem16uH,dv16uH; brccd16u_5;if result negative adddrem16uL,dv16uL; restore remainder adcdrem16uH,dv16uH clc; clear carry to be shifted into result rjmpd16u_6;else d16u_5:sec;
31、set carry to be shifted into result d16u_6:roldd16uL;shift left dividend roldd16uH roldrem16uL;shift dividend into remainder roldrem16uH subdrem16uL,dv16uL;remainder = remainder - divisor sbcdrem16uH,dv16uH; brccd16u_7;if result negative adddrem16uL,dv16uL; restore remainder adcdrem16uH,dv16uH clc;
32、clear carry to be shifted into result rjmpd16u_8;else d16u_7:sec; set carry to be shifted into result d16u_8:roldd16uL;shift left dividend roldd16uH roldrem16uL;shift dividend into remainder roldrem16uH subdrem16uL,dv16uL;remainder = remainder - divisor sbcdrem16uH,dv16uH; brccd16u_9;if result negat
33、ive adddrem16uL,dv16uL; restore remainder adcdrem16uH,dv16uH clc; clear carry to be shifted into result rjmpd16u_10;else d16u_9:sec; set carry to be shifted into result d16u_10:roldd16uL;shift left dividend roldd16uH roldrem16uL;shift dividend into remainder roldrem16uH subdrem16uL,dv16uL;remainder
34、= remainder - divisor sbcdrem16uH,dv16uH; brccd16u_11;if result negative adddrem16uL,dv16uL; restore remainder adcdrem16uH,dv16uH clc; clear carry to be shifted into result rjmpd16u_12;else d16u_11:sec; set carry to be shifted into result d16u_12:roldd16uL;shift left dividend roldd16uH roldrem16uL;s
35、hift dividend into remainder roldrem16uH subdrem16uL,dv16uL;remainder = remainder - divisor sbcdrem16uH,dv16uH; brccd16u_13;if result negative adddrem16uL,dv16uL; restore remainder adcdrem16uH,dv16uH clc; clear carry to be shifted into result rjmpd16u_14;else d16u_13:sec; set carry to be shifted int
36、o result d16u_14:roldd16uL;shift left dividend roldd16uH roldrem16uL;shift dividend into remainder roldrem16uH subdrem16uL,dv16uL;remainder = remainder - divisor sbcdrem16uH,dv16uH; brccd16u_15;if result negative adddrem16uL,dv16uL; restore remainder adcdrem16uH,dv16uH clc; clear carry to be shifted
37、 into result rjmpd16u_16;else d16u_15:sec; set carry to be shifted into result d16u_16:roldd16uL;shift left dividend roldd16uH roldrem16uL;shift dividend into remainder roldrem16uH subdrem16uL,dv16uL;remainder = remainder - divisor sbcdrem16uH,dv16uH; brccd16u_17;if result negative adddrem16uL,dv16u
38、L; restore remainder adcdrem16uH,dv16uH clc; clear carry to be shifted into result rjmpd16u_18;else d16u_17:sec; set carry to be shifted into result d16u_18:roldd16uL;shift left dividend roldd16uH roldrem16uL;shift dividend into remainder roldrem16uH subdrem16uL,dv16uL;remainder = remainder - diviso
39、r sbcdrem16uH,dv16uH; brccd16u_19;if result negative adddrem16uL,dv16uL; restore remainder adcdrem16uH,dv16uH clc; clear carry to be shifted into result rjmpd16u_20;else d16u_19:sec; set carry to be shifted into result d16u_20:roldd16uL;shift left dividend roldd16uH roldrem16uL;shift dividend into remainder roldrem16uH subdrem16uL,dv16uL;remainder = remainder - divisor sbcdrem16uH,dv16uH; brccd16u_21;if result