⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 floatpoint.asm

📁 浮点程序库
💻 ASM
字号:
 ;AVR浮点程序库
       ;清单62
       .ORG     $A00         ;THIS FRT.PLB.USE r5--r17&r0&sram $70--$7f和flagT
EXCH:   MOV     R5,R8        ;两浮点数交换子程序
        MOV     R8,R12
        MOV     R12,R5
EXCH1:  MOV     R5,R9        ;尾数交换
        MOV     R9,R13
        MOV     R13,R5
        MOV     R5,R10       ;双字节交换
        MOV     R10,R14
        MOV     R14,R5
        MOV     R5,R11
        MOV     R11,R15
        MOV     R15,R5
        RET
DP:     ANDI    R16,$7F      ;处理积/商数符,计算积/商阶码子程序
        SBRC    R9,7
        SUBI    R16,$80
        SBRC    R13,7
        SUBI    R16,$80      ;积/商符号放在r16,7
        ADD     R12,R8       ;移码相加(除数阶码已求补)
        LDI     R17,$80
        BRCC    DP1
        ADD     R12,R17      ;移码求和有进位,将和再加上$80,再有进位为溢出
        RET
DP1:    SUB     R12,R17      ;移码求和无进位,将和减去$80,有借位
        RET                  ;或差为0也为溢出
NEG3:   COM     R15          ;3字节数据求补
        COM     R14          ;先求反后加1
        COM     R13
INC3:   LDI     R17,255      
        SUB     R15,R17      ;以减去-1代替加1
        SBC     R14,R17
        SBC     R13,R17
        RET
       ;清单63               ;浮点数比较大小子程序 X1为被减数 X2为减数
FPCP:   SBRC    R9,7         ;X1为正,跳行
        RJMP    CP1          
        SBRC    R13,7        ;X2为正,跳行
        RJMP    CP2          ;X1,X2异号
FPCP1:  CP      R11,R15      ;X1,X2皆为正,以尾数低位字节,中位字节,高位字节和
        CPC     R10,R14      ;阶码的顺序(按无符号数)进行比较
        CPC     R9,R13       ;不等,阶码大者浮点数值也大;只有阶码和尾数对应相等,
        CPC     R8,R12       ;两浮点数才相等
        RET                  ;比较结果:Z=1时X1=X2,否则C=0时X1>X2,C=1时X1<X2
CP1:    SBRC    R13,7
        RJMP    CP3          ;两负数比较,转       
CP2:    CP      R13,R9       ;正数与负数比较,只比较尾数高位字节即可
        RET
CP3:    CP      R15,R11      ;X1,X2皆为负,以尾数低位字节,中位字节,高位字节和 
        CPC	    R14,R10	     ;阶码的顺序(按无符号数)进行比较
        CPC     R13,R9       ;但要将X1、X2交换位置后按正数比较过程进行
        CPC     R12,R8      
CP4:    RET                  ;比较结果:Z=1时X1=X2,否则C=0时X1>X2,C=1时X1<X2
       ;清单64
FPSU:   LDI     R17,$80      ;浮点减法子程序
        SUB     R13,R17      ;减数数符求反后作为加数
FPAD:   TST     R8           ;浮点加法子程序
        BREQ    DON1         ;被加数为0,加数为和
        TST     R12
        BRNE    FPLAD        ;加数为0,取被加数为和
SAV0:   MOV     R12,R8       ;传送被加数取代加数
        MOV     R13,R9
        MOV     R14,R10
        MOV     R15,R11      
DON1:   RET
FPLAD:  ANDI    R16,$3f      ;清除被加数,加数数符
        SBRC    R9,7
        ORI     R16,$80      ;被加数数符取到(R16,7)
        SBRC    R13,7
        ORI     R16,$40      ;加数数符取到(R16,6)
        LDI     R17,$80
        OR      R9,R17
        OR      R13,R17      ;恢复尾数最高位
        MOV     R17,R12
        SUB     R17,R8       ;计算阶差
        BREQ    GOON         ;两阶相等,转
        BRCC    NX3
        NEG     R17          ;不够减求补
        CPI     R17,24
        BRCC    EXAD          ;|阶差|>24,取被加数为和
NX2A:   LSR     R13
        ROR     R14
        ROR     R15
        DEC     R17
        BRNE    NX2A         ;加数阶小,右移加数对阶
        MOV     R12,R8       ;取被加数阶为和之阶
        BRCC    GOON
        RCALL   INC3         ;舍入移出位
        RJMP    GOON
NX3:    CPI     R17,24
        BRCC    COM1         ;阶差>24,取加数为和
LOOP:   LSR     R9
        ROR     R10
        ROR     R11
        DEC     R17
        BRNE    LOOP         ;加数阶大,右移被加数对阶
        BRCC    GOON
        RCALL   INC3A        ;舍入移出位
GOON:   SBRC    R16,6
        SUBI    R16,$80
        SBRS    R16,7        ;判别两数是否同号
        RJMP    SAMS         ;同号转
        SUB     R15,R11      ;异号,执行减法,加数为被减数
        SBC     R14,R10
        SBC     R13,R9
        BRCC    NOM          ;够减转
        SUBI    R16,$40      ;否则被减数数符求反为和之数符
        RCALL   NEG3         ;并将差求补
NOM:    MOV     R17,R13
        OR      R17,R14
        OR      R17,R15
        BREQ    DON0         ;差为0转
NMLOP:  SBRC    R13,7
        RJMP    COM1
        LSL     R15
        ROL     R14
        ROL     R13          
        DEC     R12
        BRNE    NMLOP        ;规格化
OV1:    SEV                  ;阶码变为0,下溢(可取为0,不算溢出)
        RET
SAMS:   ADD     R15,R11
        ADC     R14,R10
        ADC     R13,R9       ;两数同号,执行加法
        BRCC    COM1
        ROR     R13
        ROR     R14
        ROR     R15
        INC     R12          ;有进位时右规1次
        BREQ    OV1          ;阶码增1后变为0为上溢
        BRNC    COM1
        RCALL   INC3
COM1:   SBRC    R16,6
        RET
COMA:   LDI     R17,$7f
        AND     R13,R17      ;正数数符为0
DON:    RET
EXAD:   RCALL   SAV0         ;取被加数为和
        SBRS    R16,7
        RJMP    COMA         ;配置数符
        RET
DON0:   CLR     R12          ;浮点数为0
        RET
       ;清单65               ;浮点乘法子程序
FPMU:   TST     R8
        BREQ    M0           ;被乘数为0,积为0
        TST     R12
        BRNE    M1           ;乘数为0,积也为0
M0:     RJMP    G0           
M1:     RCALL   DP           ;处理积符号,计算积之阶码
        BRCS    OV2
        BREQ    OV2          ;判断溢出
        LDI     R17,$80
        OR      R9,R17
        OR      R13,R17      ;恢复尾数最高位
        MOV     R5,R13
        MOV     R6,R14
        MOV     R7,R15       ;乘数转入R5,R6,R7
        LDI     R17,25       ;设右移部分积次数
        CLR     R13
        CLR     R14
        CLR     R15          ;r13r14r15清除,存放积
        CLC
LOOP1:  BRCC    M2
        ADD     R15,R11
        ADC     R14,R10
        ADC     R13,R9       ;乘数右移移出位为1,被乘数加入部分积1次
M2:     ROR     R13
        ROR     R14
        ROR     R15
        ROR     R5
        ROR     R6
        ROR     R7           ;部分积连同乘数右移1位
        DEC     R17
        BRNE    LOOP1        ;尾数相乘计算完成?
        SBRC    R13,7        ;
        RJMP    M3           ;乘积最高位为1 转 
        ROL     R5
        ROL     R15
        ROL     R14
        ROL     R13          ;乘积最高位为0,高4位字节左移1位
        SBRS    R5,7
        RJMP    M5
        RCALL   INC3         ;末位字节舍入
        BRNE    M5
        SEC                  ;舍入后R13变为0
        ROR     R13          ;将其改为$80(即0.5)
        RJMP    COM2
M5:     DEC     R12          ;舍入后R13不为0
        BRNE    COM2         ;阶码减1
OV2:    SEV                  ;变为0为溢出 
        RET
M3:     SBRC    R5,7
        RCALL   INC3         ;乘积低3位字节舍入
COM2:   LDI     R17,$7f
        SBRS    R16,7
        AND     R13,R17      ;正数将符号位请除
DON2:   RET
       ;清单66
FPDI:   TST     R12          ;浮点除法子程序
        BREQ    OV3          ;除数为0,溢出
        TST     R8
        BRNE    D1
        RJMP    G0           ;被除数为0,商为0
D1:     NEG     R12          ;除数阶码求补,以加补码代替减原码
        RCALL   DP           ;处理商符号,计算商之阶码
        BRCS    OV3
        BREQ    OV3          ;判断溢出
        LDI     R17,$80
        OR      R9,R17
        OR      R13,R17      ;恢复尾数最高位
FPD3:   LDI     R17,25       ;左移相减试商25次,最后1次舍入
        SUB     R11,R15
        SBC     R10,R14
        SBC     R9,R13
        BRCS    D2           ;第一次尾数相减试商
        INC     R12          ;够减,商阶增1
        SEC
        BRNE    D3           ;商阶增1后不为0,转计商;否则为溢出
OV3:    SEV
        RET
D2:     ADD     R11,R15
        ADC     R10,R14
        ADC     R9,R13       ;不够减则恢复被除数
LOOP2:  LSL     R11
        ROL     R10
        ROL     R9           ;被除数算术左移
        BRCS    D4           ;进位位为1,够减,本位商1
        SUB     R11,R15
        SBC     R10,R14
        SBC     R9,R13       ;否则相减试商
        BRCS    D2A         
        SEC
        RJMP    D3           ;够减,本位商1
D2A:    ADD     R11,R15      ;不够减,恢复被除数
        ADC     R10,R14
        ADC     R9,R13       
        CLC                  ;本位商0
        RJMP    D3
D4:     SUB     R11,R15
        SBC     R10,R14
        SBC     R9,R13       ;被除数减去除数
D3:     DEC     R17
        BRNE    D5           ;除法未完成,循环
        MOV     R13,R5
        MOV     R14,R6
        MOV     R15,R7       ;取回商
        BRCC    COM3
        RCALL   INC3         ;第25位商舍入
COM3:   LDI     R17,$7f
        SBRS    R16,7
        AND     R13,R17      ;配置商数符
DON3:   RET
D5:     ROL     R7           ;在R5,R6,R7中记商(不必预先清除)
        ROL     R6
        ROL     R5           ;商数左移1位并记商
        RJMP    LOOP2
       ;清单67
FPSQ:   ANDI    R16,$7F      ;模拟手算开平方子程序
        SBRC    R13,7
        ORI     R16,$80     ;负数 建虚根标志
FPS0:   TST     R12
        BREQ    DON4         ;0的平方根为0
        LDI     R17,$80
        OR      R13,R17      ;恢复尾数最高位
        LSR     R12          ;阶码算术右移1位
        BRCC    FSQ2
        INC     R12          ;移出位舍入
        RCALL   INC3         ;先将位数增1(提前舍入)
        BRCS    FSQ1          ;C=1,不够减
        SEC
        ROR     R13          ;若尾数变为0将其改为0.5($80-->r13)
        RJMP    FSQ2
FSQ1:   LSR     R13
        ROR     R14
        ROR     R15          ;否则将为数算术右移
FSQ2:   LDI     R17,25       ;开出25位根,末位舍入
        MOV     R8,R17
        LDI     R17,$40
        ADD     R12,R17      ;根恢复为移码
        CLR     R5
        CLR     R6
        CLR     R7           ;根扩展区清除
        CLR     R9
        CLR     R10
        CLR     R11          ;根存储区清除
FSQ3:   SUB     R13,R17
        SBC     R7,R11
        SBC     R6,R10
        SBC     R5,R9        ;试根
        BRCS    FSQ3A
        SEC
        RJMP    FSQ4         ;够减,本位根1
FSQ3A:  ADD     R13,R17
        ADC     R7,R11
        ADC     R6,R10
        ADC     R5,R9        ;否则恢复开平方数之尾数
        CLC                  ;本位商0 
FSQ4:   DEC     R8
        BRNE    FSQ5         ;开出第25位根?
FPDON:  MOV     R13,R9
        MOV     R14,R10
        MOV     R15,R11      ;回送根尾数
        BRCC    COM4
        RCALL   INC3         ;第25位根舍入
COM4:   LDI     R17,$7F
        AND     R13,R17      ;根尾数为正数
DON4:   RET
FSQ5:   ROL     R11
        ROL     R10
        ROL     R9           ;根尾数带进位左移,记根

        LSL     R15
        ROL     R14
        ROL     R13
        ROL     R7
        ROL     R6
        ROL     R5
        LSL     R15
        ROL     R14
        ROL     R13
        ROL     R7
        ROL     R6
        ROL     R5           ;开平方数之尾数连同扩展区左移2位
        BRCC    FSQ3         ;未产生进位,循环
        RJMP    FPDON        ;否则进位为第25位根(不须试,并结束子程序)!
       ;清单68               ;牛顿迭代开平方子程序
FSQR:   TST     R12
        BREQ    SQRT         ;0的平方根为0
        ANDI    R16,$7E
        SBRC    R13,7
        ORI     R16,$80      ;虚根标志
        SBRC    R12,0
        INC     R16          ;阶码为奇数
        LDI     R17,$7F
        AND     R13,R17      ;尾数变为正数
        LSR     R12
        LDI     R17,$40
        ADC     R12,R17      ;得到根之移码
        PUSH    R12          ;暂存
        LDI     R17,$80
        MOV     R12,R17
        SBRC    R16,0
        INC     R12          ;得到X1的阶码(0.5≤X1<2)
        RCALL   LD1          ;存 X1
        LSR     R13
        ROR     R14
        ROR     R15
        LDI     R17,$40
        SBRS    R16,0        ;阶码为奇数时算术右移尾数即得到X1之尾数;否则将其最
;高位字节加上$40
        OR      R13,R17      ;得到首次根r0=(1+x1)/2
        LDI     R17,3
        MOV     R0,R17       ;迭代3次
FSQLP:  RCALL   LD2
        RCALL   GET1
        RCALL   FPDI
        RCALL   GET2
        RCALL   FPAD
        DEC     R12          ;计算r(i+1)=(x1/ri+ri)/2
        DEC     R0
        BRNE    FSQLP
        POP     R12          ;根之阶码
SQRT:   RET                  ;r16,7=1 为虚数根

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -