📄 avr32fp.inc
字号:
INT2FP: ; 16位整数转换成四字节浮点数运算子程
CLR R18
SBRC R17,7 ; R17:R16为待转换的整数
COM R18
CLR R19 ; 16位整数按数符位扩展成32位长整数
SBRC R18,7 ; 为正,R19,R18清零
COM R19 ; 为负,R19,R18置为$FFFF
LONG2FP: ; 32位长整数转换成四字节浮点数运算子程
CLR R20 ; 清符号位R20
AND R19,R19 ; 先判+/-
BRPL LONG2FP_1 ; 为正,跳至LONG2FP_1
RCALL QUBU ; 为负,调QUBU子程--取补
COM R20 ; 符号位R20取反
LONG2FP_1:
MOV R26,R16 ; 再判R19:R18:R17:R16是否全零
OR R26,R17
OR R26,R18
OR R26,R19
BRNE LONG2FP_2 ; 不为零跳至LONG2FP_2
RJMP JGW0 ; 为零跳至JGW0-结果为零
LONG2FP_2:
LDI R26,$16 ; 令R26 = 22
RJMP LONG2FP_4
LONG2FP_3:
INC R26
LSR R19
ROR R18
ROR R17
ROR R16
LONG2FP_4:
AND R19,R19 ; 判高位是否为零
BRNE LONG2FP_3 ; 不为零,右移一位,阶码加 1
LONG2FP_5:
AND R18,R18 ; 判次高位是否为零
BRNE LONG2FP_7
SUBI R26,$08 ; 为零,阶码减 8
MOV R18,R17 ; 数左移 8 位
MOV R17,R16
LDI R16,$00 ; 低位以 $00 填充
RJMP LONG2FP_5
LONG2FP_6:
DEC R26
ADD R16,R16
ADC R17,R17
ADC R18,R18
LONG2FP_7:
BRPL LONG2FP_6 ; R18第7为0,再左移一位
MOV R19,R26 ; 阶码减 1 ,直到R18第7为1
RJMP GGH
FP2INT: ; 四字节浮点数转换成16位整数运算子程
LDI R26,$0E ; 令R26 = 14
RJMP FP2LONG_1 ; 跳至FP2LONG_1
FP2LONG: ; 四字节浮点数转换成32位长整数运算子程
LDI R26,$1E ; 令R26 = 30
FP2LONG_1:
RCALL FP2LONG_11 ; 调FP2LONG_11子程
BREQ FP2LONG_4 ;相等,即阶码为 0 ,按 0 处理
SUB R26,R19 ;R26(14)-阶码差值
BREQ FP2LONG_2 ;为 0 ,则跳至FP2LONG_2
BRPL FP2LONG_5 ;为正, 则跳至FP2LONG_5-无溢出
FP2LONG_2: ;有溢出
AND R20,R20 ;符号为正,
BRMI FP2LONG_3 ;符号为负,则跳至FP2LONG_3
LDI R16,$FF
LDI R17,$FF
LDI R18,$FF
LDI R19,$7F
RET ;正向溢出,结果置为 $7F FF FF FF
FP2LONG_3:
LDI R16,$00
LDI R17,$00
LDI R18,$00
LDI R19,$80
RET ; 负向溢出,结果置为 $80 00 00 00
FP2LONG_4:
LDI R16,$00
LDI R17,$00
LDI R18,$00
LDI R19,$00
RET ;结果为 0 ,置为 $00 00 00 00
FP2LONG_5: ;无溢出
INC R19 ;阶码差值 + 1
BRMI FP2LONG_4 ;为负,即(阶码 < $7E)按零处理
LDI R19,$00 ;清R19
SUBI R26,$08 ;R26(14-阶码差值) -8
BRPL FP2LONG_7 ;为正转FP2LONG_7
SUBI R26,$F8 ;不够减则加 8
MOV R19,R18 ;左移 8 位
MOV R18,R17
MOV R17,R16
LDI R16,$7F ;低位以 $7F 填充
RJMP FP2LONG_8 ;跳至 FP2LONG_8
FP2LONG_6:
MOV R16,R17 ;右移 8 位
MOV R17,R18
LDI R18,$00 ;高位以 $00 填充
SUBI R26,$08 ;R26-8
FP2LONG_7:
CPI R26,$08 ;R26值与 8 相比较
BRCC FP2LONG_6 ;有借位,跳至FP2LONG_6
FP2LONG_8: ;无借位
AND R26,R26
BREQ FP2LONG_10
FP2LONG_9:
LSR R19 ;右移一位
ROR R18
ROR R17
ROR R16
DEC R26 ;R26-1,不为 0 跳至FP2LONG_9
BRNE FP2LONG_9 ;直到R26为 0 为止
FP2LONG_10: ;考虑符号位
SBRC R20,7
RJMP QUBU ;为负,则跳至QUBU-取补 返回
RET ;为正, 返回
FP2LONG_11:
MOV R20,R19 ; 取浮点数数符存于R20最高位
ANDI R20,$80
ADD R18,R18 ; 将阶码移至R19
ADC R19,R19
SUBI R19,$80 ; 阶码减 $80 存于R19
SEC
ROR R18 ; 恢复尾数最高位 1
CPI R19,$80 ; 阶码差值与 $80 相比较
RET
ADD32F_1: ; 存储结果
MOV R20,R25
MOV R19,R24
MOV R18,R23
MOV R17,R22
MOV R16,R21
ADD32F_2:
RJMP GGH ; 跳至GGH--处理结果
SUB32F: ; 四字节浮点减法运算子程
SUBI R24,$80 ; 减数取反,视为浮点加法运算
ADD32F: ; 四字节浮点加法运算子程
RCALL YCL ; 调YCL子程
CPI R24,$80 ;先判加数是否为 0
BREQ ADD32F_2 ;为 0 则和为被加数 跳至ADD32F_2
CPI R19,$80 ;再判被加数是否为 0
BREQ ADD32F_1 ;为 0 则和为加数 跳至ADD32F_1
ADD32F_3:
MOV R26,R19 ;转存被加数阶码
SUB R26,R24 ;R26=被加数阶码 减 加数阶码
BRVS ADD32F_2 ;溢出,跳至ADD32F_2 即加数可忽略
BRMI ADD32F_4 ;为负,跳至ADD32F_4
BRNE ADD32F_5 ;不等,跳至ADD32F_5
CP R16,R21
CPC R17,R22
CPC R18,R23
BRCC ADD32F_5
ADD32F_4:
RCALL ADD32F_16 ;调ADD32F_16,被加数和加数相交换
RJMP ADD32F_3 ;跳至ADD32F_3
ADD32F_5:
CPI R26,$18 ;阶码差值与 24 相比较
BRCS ADD32F_6 ;C=1,跳至ADD32F_6,即 < 24
CLR R21 ; > 24 加数清 0
CLR R22
CLR R23
ADD32F_6:
CPI R26,$08 ;阶码差值与 8 相比较
BRCS ADD32F_7 ;C=1,跳至ADD32F_7 (直至 < 8)
MOV R21,R22 ;加数尾数右移 8 位
MOV R22,R23 ;高 8 位清 0
CLR R23
SUBI R26,$08 ;阶码差值再减 8
RJMP ADD32F_6 ;跳至ADD32F_6
ADD32F_7:
AND R26,R26
BREQ ADD32F_9 ;直至R26=0,跳至ADD32F_9
ADD32F_8:
LSR R23 ;加数尾数右移 1 位
ROR R22
ROR R21
DEC R26 ;阶码差值减 1
BRNE ADD32F_8 ;不为 0 跳至ADD32F_8
ADD32F_9:
MOV R26,R20 ;被加数和加数是否同号
EOR R26,R25
BRMI ADD32F_10 ;异号,跳至ADD32F_10
RCALL ADD32F_13 ; 同号,调ADD32F_13子程--尾数相加
BRCC ADD32F_2 ;C=0,无溢出,跳至ADD32F_2
ROR R18 ;C=1,溢出,尾数右移 1 位
ROR R17
ROR R16
SUBI R19,$FF ;阶码加 1
BRVC ADD32F_2 ;无溢出,跳至ADD32F_2,处理结果
RJMP JGZD ;溢出,跳至JGZD ,出结果
ADD32F_10:
RCALL ADD32F_14 ;调ADD32F_14子程--尾数相减
BRNE ADD32F_11 ;不等,跳至ADD32F_11
RJMP JGW0 ;跳至JGW0 ,出结果
ADD32F_11:
BRCC ADD32F_12 ;C=0,够减,跳至ADD32F_12
RCALL ADD32F_15 ;C=1,不够减,调ADD32F_15子程--取补
ADD32F_12:
AND R18,R18 ;判R18最高位是否位 1
BRMI ADD32F_2 ;为 1 ,跳至ADD32F_2,处理结果
ADD R16,R16 ;为 0 ,尾数左移一位
ADC R17,R17
ADC R18,R18
SUBI R19,$01 ;阶码减 1
BRVC ADD32F_12 ;无溢出,跳至ADD32F_12
RJMP JGZD ;溢出,跳至JGZD ,出结果
ADD32F_13: ;尾数相加
ADD R16,R21
ADC R17,R22
ADC R18,R23
RET
ADD32F_14: ;尾数相减
SUB R16,R21
SBC R17,R22
SBC R18,R23
RET
ADD32F_15: ;结果取补
COM R17
COM R18
NEG R16
SBCI R17,$FF
SBCI R18,$FF
RET
ADD32F_16: ;两个数相交换
ST -Y,R21
ST -Y,R22
ST -Y,R23
ST -Y,R24
ST -Y,R25
MOV R24,R19
MOV R21,R16
MOV R22,R17
MOV R23,R18
MOV R25,R20
LD R20,Y+
LD R19,Y+
LD R18,Y+
LD R17,Y+
LD R16,Y+
RET
YCL:
MOV R20,R19
LDI R26,$80
ADD R18,R18
ADC R19,R19 ; 将阶码移至R19
EOR R19,R26 ; 阶码减 $80 存于R19
ADD R26,R26
ROR R18 ; 恢复尾数最高位 1
ANDI R20,$80 ;取浮点数数符存于R20最高位
MOV R25,R24
LDI R26,$80
ADD R23,R23 ; 将阶码移至R24
ADC R24,R24
EOR R24,R26 ; 阶码减 $80 存于R24
ADD R26,R26
ROR R23 ; 恢复尾数最高位 1
ANDI R25,$80 ;取浮点数数符存于R25最高位
CPI R19,$80
RET
GGH: ;规格化
ADD R18,R18 ;隐含尾数最高位为 1
LDI R26,$80 ;考虑符号位
EOR R26,R19 ;右移R26,R18
ADD R20,R20
ROR R26
ROR R18
MOV R19,R26 ;R26移至R19
RET
DIV32F_1:
ST -Y,R26 ;转存R26
CLR R13 ;清R15:R14:R13
CLR R14
CLR R15
LDI R26,$18 ;令R26=$18(24)
DIV32F_2:
CP R16,R21 ;被除数(余数)与除数两尾数相比
CPC R17,R22
CPC R18,R23
BRCS DIV32F_3 ;被除数(余数) < 除数
SUB R16,R21 ;余数 = 被除数 - 除数
SBC R17,R22
SBC R18,R23
SEC
RJMP DIV32F_4
DIV32F_3:
CLC ; 清除进位位
DIV32F_4:
ADC R13,R13 ; 商左移一位,并加上进位位
ADC R14,R14
ADC R15,R15
ADD R16,R16 ; 余数左移一位
ADC R17,R17
ADC R18,R18
DEC R26 ; R26-1
BRNE DIV32F_2 ;循环 24 次
MOV R16,R13 ;取出商
MOV R17,R14
MOV R18,R15
LD R26,Y+ ;恢复R26
RET
DIV32F: ; 四字节浮点除法运算子程
AND R24,R24
BREQ DIV32F_7 ;跳至DIV32F_7,出结果
AND R19,R19 ;判被除数是否为 0
BREQ JGW0 ;为 0 ,则结果为 0
RCALL YCL ;调YCL子程
BREQ JGW0 ;跳至JGW0, 结果为 0
EOR R20,R25 ;取商的符号位存于R20
SEC
SBC R19,R24 ;取出商的阶码
BRVS JGZD ;溢出,跳至JGZD
LSR R23 ;无溢出
ROR R22 ;将被除数与除数得尾数
ROR R21 ;右移一位,最高位置 0
LSR R18
ROR R17
ROR R16
RCALL DIV32F_1 ;调DIV32F_1子程,进行运算
AND R18,R18 ;判R18最高位是否为 0
BRMI DIV32F_5 ;为 1
ADD R16,R16 ;为 0,左移被除数尾数
ADC R17,R17
ADC R18,R18
SUBI R19,$01 ;阶码减 1
BRVS JGZD ;溢出, 跳至JGZD
DIV32F_5: ;无溢出
MOV R26,R16
LSR R26
BRCS DIV32F_6 ;进位位为 1,跳至DIV32F_6
AND R16,R16
BRPL DIV32F_6 ;为正,跳至DIV32F_6
AND R17,R17
BRPL DIV32F_6 ;为正,跳至DIV32F_6
LDI R26,$01 ;尾数加 1
ADD R16,R26
CLR R26
ADC R17,R26
ADC R18,R26
DIV32F_6:
RJMP GGH
DIV32F_7:
RJMP JGW0
JGZD: ;结果置为 $7FFFFFFF
LDI R26,$7F
MOV R19,R26
OR R18,R26
LDI R26,$FF
MOV R16,R26
MOV R17,R26
RET
JGW0: ;结果置为 $00000000
CLR R16
CLR R17
CLR R18
CLR R19
CLR R20
RET
MPY32F: ; 四字节浮点乘法运算子程
RCALL YCL ; 调YCL子程 并判乘数是否为 0
BREQ JGW0 ; 被乘数为 0 ,跳至JGW0--结果为 0
CPI R24,$80 ;判乘数是否为 0
BREQ JGW0 ;乘数为 0 ,跳至JGW0--结果为 0
EOR R20,R25 ;符号位相异或
SEC
ADC R19,R24 ;恢复阶码,存于R19
BRVS JGZD ;溢出,跳至JGZD
RCALL MPY32F_2 ;无溢出,调MPY32F_2子程
AND R18,R18 ;判R18最高位是否为 1
BRMI MPY32F_1 ;为负,即R18最高位为1跳至MPY32F_1
DEC R19 ;为正,即R18最高位为 0 阶码减 1
ADD R15,R15 ;尾数左移一位
ADC R16,R16
ADC R17,R17
ADC R18,R18 ;直至R18最高位为 1 止
MPY32F_1:
SUBI R19,$FF ;阶码加 1
BRVS JGZD ;溢出,跳至JGZD
RJMP GGH ;跳至GGH--出结果
MPY32F_2:
ST -Y,R24 ;转存R24
CLR R13 ;清R26,R15,R14,R13
CLR R14
CLR R15
CLR R26
LDI R24,$18 ;令R24=$18(24)
MPY32F_3:
ADD R13,R13 ;积的尾数在R18:R17:R16:R15:R14:R13
ADC R14,R14
ADC R15,R15
ADC R16,R16 ;尾数左移
ADC R17,R17
ADC R18,R18
BRCC MPY32F_4 ;无进位,R24减 1 ,不加乘数
ADD R13,R21 ;有进位,R24减 1 ,加乘数到尾数低位
ADC R14,R22
ADC R15,R23
ADC R16,R26
ADC R17,R26
ADC R18,R26
MPY32F_4:
DEC R24 ;循环 24 次
BRNE MPY32F_3
LD R24,Y+ ;恢复R24
RET ;取高 24 位
QUBU: ;取补运算
COM R16
COM R17
COM R18
COM R19
SUBI R16,$FF
SBCI R17,$FF
SBCI R18,$FF
SBCI R19,$FF
RET
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -