1

我在 STM32F0 上使用浮点运算(软件实现),并在清单中发现了一些奇怪的东西。一旦我使用 sqrtf,链接器就会添加 __aeabi_ddiv,它是 ~1.6kB 的内存。

此代码示例链接到 ddiv:

float value = 42.0f;
float root = sqrtf(value);

删除 sqrtf 也会删除 ddiv。所以我的问题:

  • 这是预期的行为吗?

  • 如果没有,我该如何解决。

  • 没有双倍可以做 sqrt 吗?

编译器:arm-atollic-eabi-gcc

sqrtf 列表(ddiv 在 0x800543e):

080053bc <sqrtf>:
80053bc:    b5f0        push    {r4, r5, r6, r7, lr}
80053be:    2500        movs    r5, #0
80053c0:    b08d        sub sp, #52 ; 0x34
80053c2:    1c04        adds    r4, r0, #0
80053c4:    f000 f84a   bl  800545c <__ieee754_sqrtf>
80053c8:    4b22        ldr r3, [pc, #136]  ; (8005454 <sqrtf+0x98>)
80053ca:    1c06        adds    r6, r0, #0
80053cc:    575d        ldrsb   r5, [r3, r5]
80053ce:    1c6b        adds    r3, r5, #1
80053d0:    d030        beq.n   8005434 <sqrtf+0x78>
80053d2:    1c21        adds    r1, r4, #0
80053d4:    1c20        adds    r0, r4, #0
80053d6:    f7fb febb   bl  8001150 <__aeabi_fcmpun>
80053da:    1e07        subs    r7, r0, #0
80053dc:    d12a        bne.n   8005434 <sqrtf+0x78>
80053de:    2100        movs    r1, #0
80053e0:    1c20        adds    r0, r4, #0
80053e2:    f7fb f837   bl  8000454 <__aeabi_fcmplt>
80053e6:    2800        cmp r0, #0
80053e8:    d024        beq.n   8005434 <sqrtf+0x78>
80053ea:    2301        movs    r3, #1
80053ec:    9302        str r3, [sp, #8]
80053ee:    4b1a        ldr r3, [pc, #104]  ; (8005458 <sqrtf+0x9c>)
80053f0:    1c20        adds    r0, r4, #0
80053f2:    9303        str r3, [sp, #12]
80053f4:    970a        str r7, [sp, #40]   ; 0x28
80053f6:    f7fc faad   bl  8001954 <__aeabi_f2d>
80053fa:    2200        movs    r2, #0
80053fc:    9006        str r0, [sp, #24]
80053fe:    9107        str r1, [sp, #28]
8005400:    9004        str r0, [sp, #16]
8005402:    9105        str r1, [sp, #20]
8005404:    2300        movs    r3, #0
8005406:    2d00        cmp r5, #0
8005408:    d117        bne.n   800543a <sqrtf+0x7e>
800540a:    9208        str r2, [sp, #32]
800540c:    9309        str r3, [sp, #36]   ; 0x24
800540e:    a802        add r0, sp, #8
8005410:    f000 f87a   bl  8005508 <matherr>
8005414:    2800        cmp r0, #0
8005416:    d018        beq.n   800544a <sqrtf+0x8e>
8005418:    9b0a        ldr r3, [sp, #40]   ; 0x28
800541a:    9301        str r3, [sp, #4]
800541c:    2b00        cmp r3, #0
800541e:    d004        beq.n   800542a <sqrtf+0x6e>
8005420:    f000 f874   bl  800550c <__errno>
8005424:    9b0a        ldr r3, [sp, #40]   ; 0x28
8005426:    9301        str r3, [sp, #4]
8005428:    6003        str r3, [r0, #0]
800542a:    9808        ldr r0, [sp, #32]
800542c:    9909        ldr r1, [sp, #36]   ; 0x24
800542e:    f7fc fae3   bl  80019f8 <__aeabi_d2f>
8005432:    1c06        adds    r6, r0, #0
8005434:    1c30        adds    r0, r6, #0
8005436:    b00d        add sp, #52 ; 0x34
8005438:    bdf0        pop {r4, r5, r6, r7, pc}
800543a:    0010        movs    r0, r2
800543c:    0019        movs    r1, r3
800543e:    f7fb ff55   bl  80012ec <__aeabi_ddiv>
8005442:    9008        str r0, [sp, #32]
8005444:    9109        str r1, [sp, #36]   ; 0x24
8005446:    2d02        cmp r5, #2
8005448:    d1e1        bne.n   800540e <sqrtf+0x52>
800544a:    f000 f85f   bl  800550c <__errno>
800544e:    2321        movs    r3, #33 ; 0x21
8005450:    6003        str r3, [r0, #0]
8005452:    e7e1        b.n 8005418 <sqrtf+0x5c>
8005454:    2000000c    .word   0x2000000c
8005458:    08006096    .word   0x08006096

更新我想我找到了原因,但仍然不太明白。 sqrtf的来源

双除法是异常处理的一部分,虽然 0.0/0.0 应该在编译时完成,对吧?如果我直接调用 __ieee754_sqrtf ddiv 是不链接的。这解决了我的问题,但我想知道如何使用 sqrtf 来做到这一点。

4

0 回答 0