📄 floating-point0favr.asm
字号:
;**** 数据处理 *********************************
DataTrans:
push R13 ;保护浮点运算使用寄存区
push R14
push R15
push R16
push R17
push R18
push R19
push R20
push R21
push R22
push R23
push R24
push R25
push R26
push R27
push R28
push R29
ldi YH,HIGH(DataStack)
ldi YL,LOW(DataStack)
;**** 数据处理 *********************************
pop R29
pop R28
pop R27
pop R26
pop R25
pop R24
pop R23
pop R22
pop R21
pop R20
pop R19
pop R18
pop R17
pop R16
pop R15
pop R14
pop R13
ret
;**** 四字节浮点数运算程序
;INT2FP 16 位整数转换成四字节浮点数运算子程
; 入口 r17:r16 出口r19:r18:r17:r16
; 使用的寄存器r16,r17,r18,r19,r20,r26
;LONG2FP 32 位长整数转换成四字节浮点数运算子程
; 入口r19:r18:r17:r16 出口r19:r18:r17:r16
; 使用的寄存器r16,r17,r18,r19,r20,r26
;FP2INT 四字节浮点数转换成16 位整数运算子程
; 入口 r19:r18:r17:r16 出口r19:r18
; 使用的寄存器r16,r17,r18,r19,r20,r26
;FP2LONG 四字节浮点数转换成32 位长整数运算子程
; 入口r19:r18:r17:r16 出口r19:r18:r17:r16
; 使用的寄存器r16,r17,r18,r19,r20,r26
;ADD32F 四字节浮点加法运算子程
; 入口r19:r18:r17:r16 + r24:r23:r22:r21 出口r19:r18:r17:r16
; 使用的寄存器r16,r17,r18,r19,r20,r21,r22,r23,r24,r25,r26,r28,r29
; 使用的SRAM Y-5 Y-4 Y-3 Y-2 Y-1
;SUB32F 四字节浮点减法运算子程
; 入口r19:r18:r17:r16 - r24:r23:r22:r21 出口r19:r18:r17:r16
; 使用的寄存器r16,r17,r18,r19,r20,r21,r22,r23,r24,r25,r26,r28,r29
; 使用的SRAM Y-5 Y-4 Y-3 Y-2 Y-1
;DIV32F 四字节浮点除法运算子程
; 入口r19:r18:r17:r16 / r24:r23:r22:r21 出口r19:r18:r17:r16
; 使用的寄存器r13,r14,r15,r16,r17,r18,r19,r20,r21,r22,r23,r24,r25,r26,r28,r29
; 使用的SRAM Y-1
;MPY32F 四字节浮点乘法运算子程
; 入口r19:r18:r17:r16 * r24:r23:r22:r21 出口r19:r18:r17:r16
; 使用的寄存器r13,r14,r15,r16,r17,r18,r19,r20,r21,r22,r23,r24,r25,r26,r28,r29
; 使用的SRAM Y-1
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 ;
ADD R20,R20
ROR R26 ; 右移R26,R18
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 + -