基于ARM的除法运算方法集锦

本文介绍了一种针对ARM架构的高效除法实现方法,通过使用ARM汇编语言优化标准库函数__rt_udiv和__rt_sdiv,显著提高了除法运算的速度。此方法适用于实时性要求高的嵌入式系统。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ARM每有除法指令,若程序中涉及到了“/”或“%”运算时,编译器将自动的调用库函数“__rt_udiv”和“__rt_sdiv”来实现该运算。但直接利用C库函数中的标准整数除法程序,根据执行情况和输入操作数的范围,要花费20~100个周期,消耗较多的软件运行时间。对于实时性要求很高的嵌入式系统而言,这是没法忍受了。笔者根据标准的库函数,用ARM的汇编程序实现了“__rt_udiv”和“__rt_sdiv”的功能。
 
  AREA    Divarth, CODE, READONLY
      
        EXPORT __rt_udiv
        EXPORT __rt_sdiv
;/***************************************************************/
;求除数需要移位的次数,为简化除法
;/***************************************************************/
Myclz
        mov r1,#32
Myclzstr
        cmp r0,#0
        bmi Myclzret
        add r0,r0,r0
        subs r1,r1,#1
        bne Myclzstr
Myclzret
        rsb r0,r1,#32
        mov pc,lr
;/***************************************************************/
; name : __rt_udiv
 
; in : r0 除数
;      r1 被除数
; out:r0  = r1/r0
;      r1  = r1%r0
;/***************************************************************/
__rt_udiv
          cmp  r0, #0
          IMPORT  __rt_div0  ;除数为零函数由c语言编写
          beq  __rt_div0
          cmp  r0, r1
          movhi r0, #0
          movhi pc,lr
          stmfd sp!, { r4-r7,lr}
          mov  r4, r1
          mov  r5, r0
          bl Myclz
          mov r7, r0
          mov r0,r4
          bl Myclz
          sub r7,r7,r0
          mov r5,r5,lsl r7
          mov  r0,#0
__rt_udiv_1
          add r0,r0,r0
          subs r1,r4,r5
          movhs r4,r1
          addhs r0,r0, #1
          mov   r5,r5,lsr #1
          subs  r7,r7,#1
          bcs  __rt_udiv_1
          mov r1,r4
          ldmfd sp!,{r4-r7,pc}
;/***************************************************************/
; name : __rt_sdiv
 
; in : r0 除数
;      r1 被除数
; out:r0  = r1/r0
;      r1  = r1%r0
;/***************************************************************/
__rt_sdiv 
          mov r2,#0
          cmp r0,#0
          addlt r2,r2,#1
          rsblt r0,r0,#0
          cmp  r1,#0
          addlt r2,r2,#2
          rsblt r1,r1,#0
          cmp r2,#0
          beq __rt_udiv
          stmfd sp!,{r2,lr}
          bl __rt_udiv
          ldmfd sp!,{r2}
          cmp r2,#2
          rsble r0,r0,#0
          rsbge r1,r1,#0
          ldmfd sp!, {pc}
        END
 
2.把除数取倒数,然后用乘法。倒数取法应该是个函数。
3.设a,b两个数..现要求a/b,商为c,余数为d  
  可以这样:  
                  c=0,d=0;  
                  while(a>=b)   //一定要有等号
                {  
                  c++;  
                  a=a-b;  
              }  
                d=a;

4.C库函数__rt_sdiv:
  抄   ADS1.2上的:  
   
  __rt_sdiv [0xe2102480]       ands           r2,r0,#0x80000000  
  00008140 [0x42600000]       rsbmi         r0,r0,#0  
  00008144 [0xe0323041]       eors           r3,r2,r1,asr   #32  
  00008148 [0x22611000]       rsbcs         r1,r1,#0  
  0000814c [0xe070c1a1]       rsbs           r12,r0,r1,lsr   #3  
  00008150 [0x3a000020]       bcc             0x81d8     ;   (__rt_sdiv   +   0x9c)  
  00008154 [0xe070c421]       rsbs           r12,r0,r1,lsr   #8  
  00008158 [0x3a00000f]       bcc             0x819c     ;   (__rt_sdiv   +   0x60)  
  0000815c [0xe1a00400]       mov             r0,r0,lsl   #8  
  00008160 [0xe38224ff]       orr             r2,r2,#0xff000000  
  00008164 [0xe070c221]       rsbs           r12,r0,r1,lsr   #4  
  00008168 [0x3a000017]       bcc             0x81cc     ;   (__rt_sdiv   +   0x90)  
  0000816c [0xe070c421]       rsbs           r12,r0,r1,lsr   #8  
  00008170 [0x3a000009]       bcc             0x819c     ;   (__rt_sdiv   +   0x60)  
  00008174 [0xe1a00400]       mov             r0,r0,lsl   #8  
  00008178 [0xe38228ff]       orr             r2,r2,#0xff0000  
  0000817c [0xe070c421]       rsbs           r12,r0,r1,lsr   #8  
  00008180 [0x21a00400]       movcs         r0,r0,lsl   #8  
  00008184 [0x23822cff]       orrcs         r2,r2,#0xff00  
  00008188 [0xe070c221]       rsbs           r12,r0,r1,lsr   #4  
  0000818c [0x3a00000e]       bcc             0x81cc     ;   (__rt_sdiv   +   0x90)  
  00008190 [0xe270c000]       rsbs           r12,r0,#0  
  00008194 [0x2a000383]       bcs             __rt_div0  
  00008198 [0x21a00420]       movcs         r0,r0,lsr   #8  
  0000819c [0xe070c3a1]       rsbs           r12,r0,r1,lsr   #7  
  000081a0 [0x20411380]       subcs         r1,r1,r0,lsl   #7  
  000081a4 [0xe0a22002]       adc             r2,r2,r2  
  000081a8 [0xe070c321]       rsbs           r12,r0,r1,lsr   #6  
  000081ac [0x20411300]       subcs         r1,r1,r0,lsl   #6  
  000081b0 [0xe0a22002]       adc             r2,r2,r2  
  000081b4 [0xe070c2a1]       rsbs           r12,r0,r1,lsr   #5  
  000081b8 [0x20411280]       subcs         r1,r1,r0,lsl   #5  
  000081bc [0xe0a22002]       adc             r2,r2,r2  
  000081c0 [0xe070c221]       rsbs           r12,r0,r1,lsr   #4  
  000081c4 [0x20411200]       subcs         r1,r1,r0,lsl   #4  
  000081c8 [0xe0a22002]       adc             r2,r2,r2  
  000081cc [0xe070c1a1]       rsbs           r12,r0,r1,lsr   #3  
  000081d0 [0x20411180]       subcs         r1,r1,r0,lsl   #3  
  000081d4 [0xe0a22002]       adc             r2,r2,r2  
  000081d8 [0xe070c121]       rsbs           r12,r0,r1,lsr   #2  
  000081dc [0x20411100]       subcs         r1,r1,r0,lsl   #2  
  000081e0 [0xe0a22002]       adc             r2,r2,r2  
  000081e4 [0xe070c0a1]       rsbs           r12,r0,r1,lsr   #1  
  000081e8 [0x20411080]       subcs         r1,r1,r0,lsl   #1  
  000081ec [0xe0a22002]       adc             r2,r2,r2  
  000081f0 [0xe070c001]       rsbs           r12,r0,r1  
  000081f4 [0x20411000]       subcs         r1,r1,r0  
  000081f8 [0xe0b22002]       adcs           r2,r2,r2  
  000081fc [0x2affffe5]       bcs             0x8198     ;   (__rt_sdiv   +   0x5c)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值