您的位置:首页 > 其它

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

2008-02-19 11:55 507 查看
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)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐