AVR乘除法子程序.docx
《AVR乘除法子程序.docx》由会员分享,可在线阅读,更多相关《AVR乘除法子程序.docx(24页珍藏版)》请在冰豆网上搜索。
![AVR乘除法子程序.docx](https://file1.bdocx.com/fileroot1/2023-2/2/f4ed5a47-8b9a-4e56-af49-863c24f3c7ac/f4ed5a47-8b9a-4e56-af49-863c24f3c7ac1.gif)
AVR乘除法子程序
AVR乘除法子程序
;****APPLICATIONNOTEAVR200************************
;*
;*Title:
MultiplyandDivideRoutines
;*Version:
1.1
;*Lastupdated:
97.07.04
;*Target:
AT90Sxxxx(AllAVRDevices)
;*
;*SupportE-mail:
avr@
;*
;*DESCRIPTION
;*ThisApplicationNotelistssubroutinesforthefollowing
;*Muliply/Divideapplications.Routinesarestraight-lineimplementations
;*optimizedforspeed:
;*
;*8x8=16bitunsigned
;*16x8=32bitunsigned
;*16x16=32bitunsigned
;*8/8=8+8bitunsigned
;*16/16=16+16bitunsigned
;*
;******************************************************************
.include"1200def.inc"
rjmpRESET;resethandle
;******************************************************************
;*
;*"mpy8u"-8x8BitUnsignedMultiplication
;*
;*Numberofcycles:
65
;*Lowregistersused:
None
;*Highregistersused:
3(mc8u,mp8u/m8uL,m8uH)
;*
;*Note:
ResultLowbyteandthemultipliersharethesameregister.
;*Thiscausesthemultipliertobeoverwrittenbytheresult.
;*
;******************************************************************
;*****SubroutineRegisterVariables
.defmc8u=r16;multiplicand
.defmp8u=r17;multiplier
.defm8uL=r17;resultLowbyte
.defm8uH=r18;resultHighbyte
.defcycle=r31
;*****Code
mpy8u:
ldicycle,8
clrm8uH;clearresultHighbyte
lsrmp8u;shiftmultiplier
m8u:
brccnoad80;ifcarryset
addm8uH,mc8u;addmultiplicandtoresultHighbyte
noad80:
rorm8uH;shiftrightresultHighbyte
rorm8uL;rotaterightresultLbyteandmultiplier
deccycle
brnem8u
ret
;******************************************************************
;*****2字节乘法子程序
;--------16bit*16bit----aH.aL*bH.bL=result3.2.1.0------------
;---或---16bit*8bit-----aH.aL*bL=Result3.2.1-----------------
;******************************************************************
.defaL=r16;multiplicandlowbyte//被乘数
.defaH=r17;multiplicandhighbyte
.defbL=r18;multiplierlowbyte//乘数
.defbH=r19;multiplierhighbyte
.defresult0=r18;resultbyte0(LSB)
.defresult1=r19;resultbyte1
.defresult2=r20;resultbyte2
.defresult3=r21;resultbyte3(MSB)
.defcycle=r31
;*****Code
m16_8u:
ldicycle,8
ldiR19,0
rjmpmBegin
m16_16u:
ldicycle,16
mBegin:
clrresult3;clear2highestbytesofresult
clrresult2
lsrbH;乘数/2
rorbL;C<-Rd.0Rd.0<-Rd.1Rd.15<-0
m16_16u1:
brccnoadd;若Rd.0=1//(ifcarryset)
addresult2,aL;被乘数低字节加到结果的2字节
adcresult3,aH;被乘数高字节加到结果的3字节
noadd:
rorresult3;shiftrightresultbyte3
rorresult2;rotaterightresultbyte2
rorresult1;rotateresultbyte1andmultiplierHigh
rorresult0;rotateresultbyte0andmultiplierLow
deccycle
brnem16_16u1
ret
;******************************************************************
;*
;*"div8u"-8/8BitUnsignedDivision
;*
;*Thissubroutinedividesthetworegistervariables"dd8u"(dividend)and
;*"dv8u"(divisor).Theresultisplacedin"dres8u"andtheremainderin
;*"drem8u".
;*
;*Numberofwords:
94+return
;*Lowregistersused:
1(drem8u)
;*Highregistersused:
2(dres8u/dd8u,dv8u,cycle)
;*
;******************************************************************
;*****SubroutineRegisterVariables
.defdrem8u=r15;remainder
.defdres8u=r16;result
.defdd8u=r16;dividend
.defdv8u=r17;divisor
.defcycle=r18
;*****Code**********R16/R17=R16+R15*********************
div8u:
clrdrem8u;clearremainderandcarry
ldicycle,9;8+1
d8u_0:
roldd8u;shiftleftdividend
deccycle
breqd8u_2
roldrem8u;shiftdividendintoremainder
subdrem8u,dv8u;remainder=remainder-divisor
brccd8u_1;ifresultnegative
adddrem8u,dv8u;restoreremainder
clc;clearcarrytobeshiftedintoresult
rjmpd8u_0;else
d8u_1:
sec;setcarrytobeshiftedintoresult
rjmpd8u_0
d8u_2:
ret
;******************************************************************
;*
;*"div8u"-8/8BitUnsignedDivision
;*
;*Thissubroutinedividesthetworegistervariables"dd8u"(dividend)and
;*"dv8u"(divisor).Theresultisplacedin"dres8u"andtheremainderin
;*"drem8u".
;*
;*Numberofwords:
66+return
;*Numberofcycles:
50/58/66(Min/Avg/Max)+return
;*Lowregistersused:
1(drem8u)
;*Highregistersused:
2(dres8u/dd8u,dv8u)
;*
;******************************************************************
;*****SubroutineRegisterVariables
.defdrem8u=r15;remainder
.defdres8u=r16;result
.defdd8u=r16;dividend
.defdv8u=r17;divisor
;*****Code
div8u:
subdrem8u,drem8u;clearremainderandcarry
roldd8u;shiftleftdividend
roldrem8u;shiftdividendintoremainder
subdrem8u,dv8u;remainder=remainder-divisor
brccd8u_1;ifresultnegative
adddrem8u,dv8u;restoreremainder
clc;clearcarrytobeshiftedintoresult
rjmpd8u_2;else
d8u_1:
sec;setcarrytobeshiftedintoresult
d8u_2:
roldd8u;shiftleftdividend
roldrem8u;shiftdividendintoremainder
subdrem8u,dv8u;remainder=remainder-divisor
brccd8u_3;ifresultnegative
adddrem8u,dv8u;restoreremainder
clc;clearcarrytobeshiftedintoresult
rjmpd8u_4;else
d8u_3:
sec;setcarrytobeshiftedintoresult
d8u_4:
roldd8u;shiftleftdividend
roldrem8u;shiftdividendintoremainder
subdrem8u,dv8u;remainder=remainder-divisor
brccd8u_5;ifresultnegative
adddrem8u,dv8u;restoreremainder
clc;clearcarrytobeshiftedintoresult
rjmpd8u_6;else
d8u_5:
sec;setcarrytobeshiftedintoresult
d8u_6:
roldd8u;shiftleftdividend
roldrem8u;shiftdividendintoremainder
subdrem8u,dv8u;remainder=remainder-divisor
brccd8u_7;ifresultnegative
adddrem8u,dv8u;restoreremainder
clc;clearcarrytobeshiftedintoresult
rjmpd8u_8;else
d8u_7:
sec;setcarrytobeshiftedintoresult
d8u_8:
roldd8u;shiftleftdividend
roldrem8u;shiftdividendintoremainder
subdrem8u,dv8u;remainder=remainder-divisor
brccd8u_9;ifresultnegative
adddrem8u,dv8u;restoreremainder
clc;clearcarrytobeshiftedintoresult
rjmpd8u_10;else
d8u_9:
sec;setcarrytobeshiftedintoresult
d8u_10:
roldd8u;shiftleftdividend
roldrem8u;shiftdividendintoremainder
subdrem8u,dv8u;remainder=remainder-divisor
brccd8u_11;ifresultnegative
adddrem8u,dv8u;restoreremainder
clc;clearcarrytobeshiftedintoresult
rjmpd8u_12;else
d8u_11:
sec;setcarrytobeshiftedintoresult
d8u_12:
roldd8u;shiftleftdividend
roldrem8u;shiftdividendintoremainder
subdrem8u,dv8u;remainder=remainder-divisor
brccd8u_13;ifresultnegative
adddrem8u,dv8u;restoreremainder
clc;clearcarrytobeshiftedintoresult
rjmpd8u_14;else
d8u_13:
sec;setcarrytobeshiftedintoresult
d8u_14:
roldd8u;shiftleftdividend
roldrem8u;shiftdividendintoremainder
subdrem8u,dv8u;remainder=remainder-divisor
brccd8u_15;ifresultnegative
adddrem8u,dv8u;restoreremainder
clc;clearcarrytobeshiftedintoresult
rjmpd8u_16;else
d8u_15:
sec;setcarrytobeshiftedintoresult
d8u_16:
roldd8u;shiftleftdividend
ret
;------------------div16_8u----16/8bit----R20R19/R18=R20R19+R17R16-------------------
.defdres16uL=r19
.defdres16uH=r20
.defdd16uL=r19
.defdd16uH=r20
.defdv8u=r18
.defdcnt16u=r22
.defdrem16uL=r16
.defdrem16uH=r17
div16_8u:
clrdrem16uL;clearremainderLowbyte
subdrem16uH,drem16uH;clearremainderHighbyteandcarry
ldidcnt16u,17
d16u_1:
roldd16uL;shiftleftdividend
roldd16uH
decdcnt16u
breqd16u_3;完成?
跳出
roldrem16uL;shiftdividendintoremainder
roldrem16uH
subdrem16uL,dv8u;remainder=remainder-divisor
brccd16u_2;ifresultnegative
adddrem16uL,dv8u;restoreremainder
clc;clearcarrytobeshiftedintoresult
rjmpd16u_1;else
d16u_2:
sec
rjmpd16u_1
d16u_3:
ret
;--------------------------------16bit/16bit-----------------------------------------
.defdrem16uL=r14
.defdrem16uH=r15
.defdres16uL=r16
.defdres16uH=r17
.defdd16uL=r16
.defdd16uH=r17
.defdv16uL=r18
.defdv16uH=r19
.defdcnt16u=r20
;*****Code
div16u:
clrdrem16uL;clearremainderLowbyte
subdrem16uH,drem16uH;clearremainderHighbyteandcarry
ldidcnt16u,17
d16u_1:
roldd16uL;shiftleftdividend
roldd16uH
decdcnt16u
breqd16u_3;完成?
跳出
roldrem16uL;shiftdividendintoremainder
roldrem16uH
subdrem16uL,dv16uL;remainder=remainder-divisor
sbcdrem16uH,dv16uH;
brccd16u_2;ifresultnegative
adddrem16uL,dv16uL;restoreremainder
adcdrem16uH,dv16uH
clc;clearcarrytobeshiftedintoresult
rjmpd16u_1;else
d16u_2:
sec
rjmpd16u_1
d16u_3:
ret
;******************************************************************
;*
;*"div16u"-16/16BitUnsignedDivision
;*
;*Thissubroutinedividesthetwo16-bitnumbers
;*"dd8uH:
dd8uL"(dividend)and"dv16uH:
dv16uL"(divisor).
;*Theresultisplacedin"dres16uH:
dres16uL"andtheremainderin
;*"drem16uH:
drem16uL".
;*
;*Numberofwords:
196+return
;*Numberofcycles:
148/173/196(Min/Avg/Max)
;*Lowregistersused:
2(drem16uL,drem16uH)
;*Highregistersused:
4(dres16uL/dd16uL,dres16uH/dd16uH,dv16uL,dv16uH)
;*
;******************************************************************
;*****SubroutineRegisterVariables
.defdrem1