AVR汇编百例浮点程序库.docx
《AVR汇编百例浮点程序库.docx》由会员分享,可在线阅读,更多相关《AVR汇编百例浮点程序库.docx(49页珍藏版)》请在冰豆网上搜索。
![AVR汇编百例浮点程序库.docx](https://file1.bdocx.com/fileroot1/2023-1/26/f7925e23-ec94-482f-8432-82f26d3c04e3/f7925e23-ec94-482f-8432-82f26d3c04e31.gif)
AVR汇编百例浮点程序库
;范例62
.ORG$A00
EXCH:
MOVR5,R8;两浮点数交换子程序
MOVR8,R12
MOVR12,R5
EXCH1:
MOVR5,R9;尾数交换
MOVR9,R13
MOVR13,R5
MOVR5,R10;双字节交换
MOVR10,R14
MOVR14,R5
MOVR5,R11
MOVR11,R15
MOVR15,R5
RET
DP:
ANDIR16,$7F;处理积/商数符,计算积/商阶码子程序
SBRCR9,7
SUBIR16,$80
SBRCR13,7
SUBIR16,$80;积/商符号放在r16,7
ADDR12,R8;移码相加(除数阶码已求补)
LDIR17,$80
BRCCDP1
ADDR12,R17;移码求和有进位,将和再加上$80,再有进位为溢出
RET
DP1:
SUBR12,R17;移码求和无进位,将和减去$80,有借位
RET;或差为0也为溢出
NEG3:
COMR15;3字节数据求补
COMR14;先求反后加1
COMR13
INC3:
LDIR17,255
SUBR15,R17;以减去-1代替加1
SBCR14,R17
SBCR13,R17
RET
;范例63;浮点数比较大小子程序X1为被减数X2为减数
FPCP:
SBRCR9,7;X1为正,跳行
RJMPCP1
SBRCR13,7;X2为正,跳行
RJMPCP2;X1,X2异号
FPCP1:
CPR11,R15;X1,X2皆为正,以尾数低位字节,中位字节,高位字节和
CPCR10,R14;阶码的顺序(按无符号数)进行比较
CPCR9,R13;不等,阶码大者浮点数值也大;只有阶码和尾数对应相等,
CPCR8,R12;两浮点数才相等
RET;比较结果:
Z=1时X1=X2,否则C=0时X1>X2,C=1时X1CP1:
SBRCR13,7
RJMPCP3;两负数比较,转
CP2:
CPR13,R9;正数与负数比较,只比较尾数高位字节即可
RET
CP3:
CPR15,R11;X1,X2皆为负,以尾数低位字节,中位字节,高位字节和
CPCR14,R10;阶码的顺序(按无符号数)进行比较
CPCR13,R9;但要将X1、X2交换位置后按正数比较过程进行
CPCR12,R8
CP4:
RET;比较结果:
Z=1时X1=X2,否则C=0时X1>X2,C=1时X1;范例64
FPSU:
LDIR17,$80;浮点减法子程序
SUBR13,R17;减数数符求反后作为加数
FPAD:
TSTR8;浮点加法子程序
BREQDON1;被加数为0,加数为和
TSTR12
BRNEFPLAD;加数为0,取被加数为和
SAV0:
MOVR12,R8;传送被加数取代加数
MOVR13,R9
MOVR14,R10
MOVR15,R11
DON1:
RET
FPLAD:
ANDIR16,$3f;清除被加数,加数数符
SBRCR9,7
ORIR16,$80;被加数数符取到(R16,7)
SBRCR13,7
ORIR16,$40;加数数符取到(R16,6)
LDIR17,$80
ORR9,R17
ORR13,R17;恢复尾数最高位
MOVR17,R12
SUBR17,R8;计算阶差
BREQGOON;两阶相等,转
BRCCNX3
NEGR17;不够减求补
CPIR17,24
BRCCEXAD;|阶差|>24,取被加数为和
NX2A:
LSRR13
RORR14
RORR15
DECR17
BRNENX2A;加数阶小,右移加数对阶
MOVR12,R8;取被加数阶为和之阶
BRCCGOON
RCALLINC3;舍入移出位
RJMPGOON
NX3:
CPIR17,24
BRCCCOM1;阶差>24,取加数为和
LOOP:
LSRR9
RORR10
RORR11
DECR17
BRNELOOP;加数阶大,右移被加数对阶
BRCCGOON
RCALLINC3A;舍入移出位
GOON:
SBRCR16,6
SUBIR16,$80
SBRSR16,7;判别两数是否同号
RJMPSAMS;同号转
SUBR15,R11;异号,执行减法,加数为被减数
SBCR14,R10
SBCR13,R9
BRCCNOM;够减转
SUBIR16,$40;否则被减数数符求反为和之数符
RCALLNEG3;并将差求补
NOM:
MOVR17,R13
ORR17,R14
ORR17,R15
BREQDON0;差为0转
NMLOP:
SBRCR13,7
RJMPCOM1
LSLR15
ROLR14
ROLR13
DECR12
BRNENMLOP;规格化
OV1:
SEV;阶码变为0,下溢(可取为0,不算溢出)
RET
SAMS:
ADDR15,R11
ADCR14,R10
ADCR13,R9;两数同号,执行加法
BRCCCOM1
RORR13
RORR14
RORR15
INCR12;有进位时右规1次($7F+1=$80溢出)
BREQOV1;阶码增1后变为0为上溢
BRNCCOM1
RCALLINC3
COM1:
CLV
SBRCR16,6
RET
COMA:
LDIR17,$7F
ANDR13,R17;正数数符为0
DON:
RET
EXAD:
RCALLSAV0;取被加数为和
SBRSR16,7
RJMPCOMA;配置数符
RET
DON0:
CLRR12;浮点数为0
RET
;范例65;浮点乘法子程序
FPMU:
TSTR8
BREQM0;被乘数为0,积为0
TSTR12
BRNEM1;乘数为0,积也为0
M0:
RJMPG0
M1:
RCALLDP;处理积符号,计算积之阶码
BRCSOV2
BREQOV2;判断溢出
LDIR17,$80
ORR9,R17
ORR13,R17;恢复尾数最高位
MOVR5,R13
MOVR6,R14
MOVR7,R15;乘数转入R5,R6,R7
LDIR17,25;设右移部分积次数
CLRR13
CLRR14
CLRR15;r13r14r15清除,存放积
CLC
LOOP1:
BRCCM2
ADDR15,R11
ADCR14,R10
ADCR13,R9;乘数右移移出位为1,被乘数加入部分积1次
M2:
RORR13
RORR14
RORR15
RORR5
RORR6
RORR7;部分积连同乘数右移1位
DECR17
BRNELOOP1;尾数相乘计算完成?
SBRCR13,7
RJMPM3;乘积最高位为1转
ROLR5
ROLR15
ROLR14
ROLR13;乘积最高位为0,高4位字节左移1位
SBRSR5,7
RJMPM5
RCALLINC3;末位字节舍入
BRNEM5
SEC;舍入后R13变为0
RORR13;将其改为$80(即0.5)
RJMPCOM2
M5:
DECR12;舍入后R13不为0
BRNECOM2;阶码减1
OV2:
SEV;变为0为溢出
RET
M3:
SBRCR5,7
RCALLINC3;乘积低3位字节舍入
COM2:
LDIR17,$7F
SBRSR16,7
ANDR13,R17;正数将符号位请除
DON2:
CLV
RET
;范例66
FPDI:
TSTR12;浮点除法子程序
BREQOV3;除数为0,溢出
TSTR8
BRNED1
RJMPG0;被除数为0,商为0
D1:
NEGR12;除数阶码求补,以加补码代替减原码
RCALLDP;处理商符号,计算商之阶码
BRCSOV3
BREQOV3;判断溢出
LDIR17,$80
ORR9,R17
ORR13,R17;恢复尾数最高位
FPD3:
LDIR17,25;左移相减试商25次,最后1次舍入
SUBR11,R15
SBCR10,R14
SBCR9,R13
BRCSD2;第一次尾数相减试商
INCR12;够减,商阶增1
SEC
BRNED3;商阶增1后不为0,转计商;否则为溢出
OV3:
SEV
RET
D2:
ADDR11,R15
ADCR10,R14
ADCR9,R13;不够减则恢复被除数
LOOP2:
LSLR11
ROLR10
ROLR9;被除数算术左移
BRCSD4;进位位为1,够减,本位商1
SUBR11,R15
SBCR10,R14
SBCR9,R13;否则相减试商
BRCSD2A
SEC
RJMPD3;够减,本位商1
D2A:
ADDR11,R15;不够减,恢复被除数
ADCR10,R14
ADCR9,R13
CLC;本位商0
RJMPD3
D4:
SUBR11,R15
SBCR10,R14
SBCR9,R13;被除数减去除数
D3:
DECR17
BRNED5;除法未完成,循环(1-1=0,不溢出)
MOVR13,R5
MOVR14,R6
MOVR15,R7;取回商
BRCCCOM3
RCALLINC3;第25位商舍入($800000-$FFFFFF不溢出,故INC3不会溢出!
)
COM3:
LDIR17,$7F
SBRSR16,7
ANDR13,R17;配置商数符
DON3:
RET
D5:
ROLR7;在R5,R6,R7中记商(不必预先清除)
ROLR6
ROLR5;商数左移1位并记商
RJMPLOOP2
;范例67
FPSQ:
ANDIR16,$7F;模拟手算开平方子程序
SBRCR13,7
ORIR16,$80;负数建虚根标志
FPS0:
TSTR12
BREQDON4;0的平方根为0
LDIR17,$80
ORR13,R17;恢复尾数最高位
LSRR12;阶码算术右移1位
BRCCFSQ2
INCR12;移出位舍入
RCALLINC3;先将位数增1(提前舍入)
BRCSFSQ1;C=1,不够减
SEC
RORR13;若尾数变为0将其改为0.5($80-->r13)
RJMPFSQ2
FSQ1:
LSRR13
RORR14
RORR15;否则将为数算术右移
FSQ2:
LDIR17,25;开出25位根,末位舍入
MOVR8,R17
LDIR17,$40
ADDR12,R17;根恢复为移码
CLRR5
CLRR6
CLRR7;根扩展区清除
CLRR9
CLRR10
CLRR11;根存储区清除
FSQ3:
SUBR13,R17
SBCR7,R11
SBCR6,R10
SBCR5,R9;试根
BRCSFSQ3A
SEC
RJMPFSQ4;够减,本位根1
FSQ3A:
ADDR13,R17
ADCR7,R11
ADCR6,R10
ADCR5,R9;否则恢复开平方数之尾数
CLC;本位商0
FSQ4:
DECR8
BRNEFSQ5;开出第25位根?
FQDON:
MOVR13,R9
MOVR14,R10
MOVR15,R11;回送根尾数
BRCCCOM4
RCALLINC3;第25位根舍入
COM4:
LDIR17,$7F
ANDR13,R17;根尾数为正数
DON4:
RET
FSQ5:
ROLR11
ROLR10
ROLR9;根尾数带进位左移,记根
LSLR15
ROLR14
ROLR13
ROLR7
ROLR6
ROLR5
LSLR15
ROLR14
ROLR13
ROLR7
ROLR6
ROLR5;开平方数之尾数连同扩展区左移2位
BRCCFSQ3;未产生进位,循环
RJMPFQDON;否则进位为第25位根(不须试,并结束子程序)!
;范例68;牛顿迭代开平方子程序
FSQR:
TSTR12
BREQSQRT;0的平方根为0
ANDIR16,$7E
SBRCR13,7
ORIR16,$80;虚根标志
SBRCR12,0
INCR16;阶码为奇数
LDIR17,$7F
ANDR13,R17;尾数变为正数
LSRR12
LDIR17,$40
ADCR12,R17;得到根之移码
PUSHR12;暂存
LDIR17,$80
MOVR12,R17
SBRCR16,0
INCR12;得到X1的阶码(0.5≤X1<2)
RCALLLD1;存X1
LSRR13
RORR14
RORR15
LDIR17,$40
SBRSR16,0;阶码为奇数时算术右移尾数即得到X1之尾数;否则将其最
;高位字节加上$40
ORR13,R17;得到首次根r0=(1+x1)/2
LDIR17,3
MOVR0,R17;迭代3次
FSQLP:
RCALLLD2
RCALLGET1
RCALLFPDI
RCALLGET2
RCALLFPAD
DECR12;计算r(i+1)=(x1/ri+ri)/2
DECR0
BRNEFSQLP;r3的尾数为根之尾数
POPR12;取回根之阶码
SQRT:
RET;r16,7=1为虚数根
;范例69;基本运算程序的演示程序
DMST1:
.EQUSPL=$3D
.EQUSPH=$3E
LDIR16,2;high(ramend)
OUTSPH,R16
LDIR16,$5F;low(ramend)
OUTSPL,R16
LDSR11,$60;r11,7:
数符r11,6:
阶符r11,5--0:
阶(最大为38)
LDSR12,$61;r12-r15:
尾数
LDSR13,$62
LDSR14,$63
LDSR15,$64;尾数共8位BCD码
RCALLDTOB;转为二进制浮点数
RCALLLD2;暂存
LDSR11,$65;r11,7:
数符r11,阶符r11,5--0:
阶(最大为38)
LDSR12,$66;r12-r15:
尾数
LDSR13,$67
LDSR14,$68
LDSR15,$69
RCALLDTOB;转为二进制浮点数
RCALLGET2;取第一操作数
RCALLFPAD;调基本运算子程序之一(FPSU/FPMU/FPDI)
RCALLBTOD;转回十进制浮点数
DMRET:
RJMPDMRET
;范例70;辅助子程序
KP2:
MOVR8,R12;复制第二操作数
MOVR9,R13
MOVR10,R14
MOVR11,R15
RET
LD1:
STS$70,R12;存浮点数
STS$71,R13
STS$72,R14
SYS$73,R15
RET
LD2:
STS$74,R12;存浮点数
STS$75,R13
STS$76,R14
STS$77,R15
RET
LD3:
STS$78,R12;存浮点数
STS$79,R13
STS$7A,R14
STS$7B,R15
RET
GET1:
LDSR8,$70;取浮点数
LDSR9,$71
LDSR10,$72
LDSR11,$73
RET
GET2:
LDSR8,$74;取浮点数
LDSR9,$75
LDSR10,$76
LDSR11,$77
RET
GET3:
LDSR8,$78;取浮点数
LDSR9,$79
LDSR10,$7A
LDSR11,$7B
RET
INVPI:
LDIR17,$86;取浮点数180/л
MOVR8,R17
LDIR17,$65
MOVR9,R17
LDIR17,$2E
MOVR10,R17
LDIR17,$E1
MOVR11,R17
RET
G90:
LDIR17,$87;取浮点数90
MOVR8,R17
LDIR17,$34
MOVR9,R17
CLRR10
CLRR11
RET
DTOR:
RCALLPI18;角度化为弧度
RJMPFPMU
RTOD:
RCALLINVPI;弧度化为角度
RJMPFPMU
GHPI:
LDIR17,$81;取浮点数л/2
MOVR8,R17
LDIR17,$49
MOVR9,R17
LDIR17,$0f
MOVR10,R17
LDIR17,$DB
MOVR11,R17
RET
G01:
LDIR17,$7D;取浮点数0.1
MOVR8,R17
LDIR17,$4C
MOVR9,R17
LDIR17,$CC
MOVR10,R17
LDIR17,$CD
MOVR11,R17
RET
G1:
LDIR17,$81;取浮点数1
MOVR8,R17
CLRR9
CLRR10
CLRR11
RET
PI18:
LDIR17,$7B;取浮点数л/180
MOVR8,R17
LDIR17,$0E
MOVR9,R17
LDIR17,$FA
MOVR10,R17
LDIR17,$35
MOVR11,R17
RET
GINT:
LDIR17,R12;浮点数取整
CPIR17,$81
BRCCGINT1
RCALLG0;阶码<$81,结果为0
RJMPKP2
GINT1:
ANDIR16,$DD
SBRCR13,7
ORIR16,2;记数符
CPIR17,$98
BRCCGOVER;阶码>$97,溢出
RCALLBRK;分解出整数部分(在R9R10R11)
SBRSR16,1
RET;正数返回
NEG3A:
COMR11;负数求(r9r10r11)之补
COMR10
COMR9
INC3A:
LDIR17,255
SUBIR11,R17
SBCIR10,R17
SBCIR9,R17;求反后加1
RET
GOVER:
ORIR16,$20;设整数部分超过23位标志
RET
BRK:
ANDIR16,$DF;将正浮点数分解为整数/小数两部分
LDIR17,$80
ORR13,R17;恢复尾数最高位
CLRR9
CLRR10
CLRR11
MOVR17,R12
SUBIR17,$80
BREQBRKRT
BRCSLOOPT
CPIR17,$19;整数部分超过24位
BRCCGOVER;为溢出
LOOP4:
LSLR15
ROLR14
ROLR13
ROLR11
ROLR10
ROLR9
DECR17
BRNELOOPT;左移位数为阶码-$80,整数部分进入r9-r11中
BRKRT:
RET
LOOPT:
LSRR13;只有小数部分右移尾数($80-阶码)位
RORR14
RORR15
INCR17
BRNELOOPT
RET
NRML:
ANDIR16,$BF;1字节正整数(在R13中)规格化为浮点数
CLRR14
CLRR15
LDIR12,$88;设阶码
RJMPNMLOP
G10:
LDIR17,$84;取浮点数10
MOVR8,R17
LDIR17,$20
MOVR9,R17
CLRR10
CLRR11
RET
GLN2:
LDIR17,$80;取浮点数ln2(=0.6931471806)
MOVR8,R17
LDIR17,$31
MOVR9,R17
LDIR17,$72
MOVR10,R17
LDIR17,$18
MOVR11,R17
RET
GLN10:
LDIR17,$82;取浮点数ln10(=2.302585093)
MOVR8,R17
LDIR17,$13
MOVR9,R17
LDIR17,$5D
MOVR10,R17
LDIR17,$8E
MOVR11,R17
RET
INVX:
TSTR12;计算1/X,X=0时溢出
BRNEINV
OV4:
SEV
RET
INV:
RCALLG1;取1
RJMPFPDI
;范例71;用荷纳法计算多项式值子程序
FPLN1:
ORIR16,$10;设计算奇函数(lnx,sinx,arcsinx等)标志
RCALLLD3;存X
RCALLKP2
RCALLFPMU;计算X2
RJMPFLN0;
FPLN2:
ANDIR16,$EF;设计算偶函数(EXP,COSX等)标志
FLN0:
RCALLLD1;存T,T=X或T=X2
POPR30
POPR31;系数表数据地址进入Z
LSLR30
ROLR31;由按字取数变为按字节取数
LPM;r0<--(z)取阶码
MOVR8,R0
ADIWR30,1;指针增1
LPM;取尾数高位字节
MOVR9,R0
ADIWR30,1;z+1
LPM;取尾数中