|
本帖最后由 paulhyde 于 2014-9-15 08:58 编辑
- //==============================================================================================
- // ----Function: float Float_DIV(float Data_A,float Data_B);
- // -Description: 浮点除法运算子程序
- // 最大执行时间53.3us -- 1280 Cycle (24MHz):这个时间包括参数传递和现场保护,参数返回
- // --Parameters: 被除数/除数
- // -----Returns: 结果,浮点数
- // -------Notes: 和标准库相比,节约3000个Cycle左右。在运算溢出时,返回的指数为0xff,但数符为运算结果的数符
- //==============================================================================================
- .PUBLIC _Float_DIV
- _Float_DIV:
- push bp,bp to [sp]
- bp = sp + 1
- r2 = [bp + 5]
- r2 |= [bp + 6]
- jz ?ACC_over //第二个参数为零则转
- r2 = [bp + 3] //判断是不是有参数为零,为零结果肯定是零
- r2 |= [bp + 4]
- jnz ?ACC_zero //第一个参数为零则转
- ?DIV_zer //运算结果太小,直接置为零
- r2 = 0 //高字
- r1 = 0 //低字
- pop bp,bp from [sp]
- retf
- ?ACC_over: //运算溢出
- r2 = r1 ^ 0x7fff //返回的指数为0xff
- r1 = 0xffff //所有尾数的位为1
- pop bp,bp from [sp]
- retf
- ?ACC_zer //结果不为零,向下执行
- r4 = [bp + 4] //第一个参数的高字
- r3 = [bp + 6] //第二个参数的高字
- //计算阶码
- r2 = r4 & 0x7f80 //第一个参数的阶码
- r1 = r3 & 0x7f80 //第二个参数的阶码
- r2 -= r1
- r2 += 0x3f00 //获得结果的阶码
- cmp r2,0x7f80
- jae ?ACC_over //如果运算溢出则转到?sum_over
- cmp r2,0x0080
- jb ?DIV_zero //阶码小于等于0,结果为零
- r1 = r3 //计算符号
- r1 ^= r4
- r1 &= 0x8000 //计算结果的符号
- r4 &= 0x7f
- r4 |= 0x80 //尾数恢复
- [bp + 4] = r4 //保存尾数高字
- r3 &= 0x7f
- r3 |= 0x80 //尾数恢复
- [bp + 6] = r3 //保存尾数高字
- cmp r4,r3 //先比较高位
- jne ?DIV_Adj
- r3 = [bp + 3] //比较低位
- cmp r3,[bp + 5]
- jne ?DIV_Adj
- //尾数相等,商为1,数据规格化,调整商阶
- r2 += 0x80 //指数调整
- cmp r2,0x7f80
- jae ?ACC_over //如果运算溢出则转到?sum_over
- r2 |= r1 //获得符号位
- r1 = 0 //尾数为零
- pop bp,bp from [sp]
- retf
- ?DIV_Adj: //被除数和指数调整
- jb ?DIV_next //小的话就直接执行除法
- r3 = [bp + 3] //调整数据后再除,被除数减去除数
- r3 -= [bp + 5]
- [bp + 3] = r3
- r3 = [bp + 4]
- r3 -= [bp + 6],carry
- [bp + 4] = r3
- r2 += 0x80 //商阶加1
- cmp r2,0x7f80
- jae ?ACC_over //如果运算溢出则转到?sum_over
- r2 |= r1
- [sp --] = r2 //分配一个临时空间,并用来存结果的阶码和符号位
- call _Uint24_F_DIV //除法获得的结果直接作为尾数
- //结果在[bp + 4],[bp + 3]中
- r2 = [bp + 4] //四舍五入
- r1 = [bp + 3]
- r1 += 1
- r2 += 0,carry
- r2 = r2 lsr 1
- r3 = r2 lsr 3
- r1 = r1 ror 1
- r2 |= [++ sp]
- pop bp,bp from [sp]
- retf
- ?DIV_next:
- r2 |= r1
- [sp --] = r2 //分配一个临时空间,并用来存结果的阶码和符号位
- call _Uint24_F_DIV //不用调整时,除法获得的结果左移一位规格化
- r2 = [bp + 4] //结果在[bp + 4],[bp + 3]中
- r2 &= 0x7f
- r2 |= [++ sp]
- r1 = [bp + 3]
- pop bp,bp from [sp]
- retf
- _Uint24_F_DIV: //结果存到[bp + 4],[bp + 3]中
- r2 = [bp + 4]
- r1 = [bp + 3]
- r4 = 0 //清结果寄存器
- r3 = 8 //算高8位结果
- ?Uint24_Loop:
- r4 += r4 //商和被除数整体左移一位
- r1 += r1,carry
- r2 += r2,carry //前8位时绝对不会有高位移出为1的情况
- r1 -= [bp + 5] //相减判溢出
- r2 -= [bp + 6],Carry
- jcs ?Uint24_ADD1 //够减则转
- r1 += [bp + 5] //不够减,被除数恢复
- r2 += [bp + 6],Carry
- r3 -= 1
- jnz ?Uint24_Loop
- jmp ?Uint24_Loop1
- ?Uint24_ADD1:
- r4 += 1
- r3 -= 1
- jnz ?Uint24_Loop
- ?Uint24_Loop1:
- [bp + 4] = r4 //存结果的高8位
- r4 = 0
- r3 = 16 //算后16位结果
- ?Uint24_Loop2:
- r4 += r4
- r1 += r1,carry
- r2 += r2,carry
- jcs ?Uint24_SUB_ADD2
- r1 -= [bp + 5]
- r2 -= [bp + 6],Carry
- jcs ?Uint24_ADD2
- r1 += [bp + 5] //被除数恢复
- r2 += [bp + 6],Carry
- r3 -= 1
- jnz ?Uint24_Loop2
- ?Uint24_5_Adj: //尾数的四舍五入
- r1 += r1 //试商25位结果,并做四舍五入处理
- r2 += r2,carry
- cmp r2,[bp + 6]
- jne ?Uint24_5ON_Adj
- cmp r1,[bp + 5]
- ?Uint24_5ON_Adj:
- jb ?Uint24_exit
- r4 += 1
- r3 = [bp + 4]
- r3 += 0,carry
- [bp + 4] = r3
- ?Uint24_exit:
- [bp + 3] = r4
- retf
- ?Uint24_SUB_ADD2:
- r1 -= [bp + 5]
- r2 -= [bp + 6],Carry
- ?Uint24_ADD2:
- r4 += 1
- r3 -= 1
- jnz ?Uint24_Loop2
- jmp ?Uint24_5_Adj
复制代码
|
|