来自libm的函数sinf不会在ARM QEMU机器上返回

时间:2014-01-05 17:16:00

标签: gcc arm qemu libm

我正在尝试在使用QEMU模拟的ARM机器上运行以下代码。

#include "math.h"

// Newlib doesn't implement this function.
void _exit(int status) {
    while (1);
}

int main() {
  float a = 1.25;

  float b = sinf(a);
  return 0;
}

二手工具链:

$ arm-none-eabi-gcc --version
arm-none-eabi-gcc (GNU Tools for ARM Embedded Processors) 4.8.3 20131129 (release) [ARM/embedded-4_8-branch revision 205641]
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

代码编译为:

arm-none-eabi-gcc -g -o math.elf math.c -lm

QEMU机器启动为:

$ qemu-system-arm -M realview-pbx-a9 -cpu cortex-a9 -kernel math.elf -nographic -serial /dev/null -s -S

GDB会话如下:

(gdb) target remote localhost:1234
Remote debugging using localhost:1234
0x00008104 in _start ()
(gdb) set $pc = 0x822c
(gdb) break *0x8240
Breakpoint 1 at 0x8240: file math.c, line 10.
(gdb) break *0x824c
Breakpoint 2 at 0x824c: file math.c, line 11.
(gdb) c
Continuing.

Breakpoint 1, main () at math.c:10
10    float b = sinf(a);
(gdb) c
Continuing.

断点2设置在最后一行(返回0)。从GDB会话日志中可以看出,永远不会到达第二个断点。计算只是陷入了sinf函数。知道为什么吗?

我正在尝试直接在ARM程序集中编写的类似代码,结果是一样的。

2 个答案:

答案 0 :(得分:0)

看起来我误用了gdb。我还测试了ARM-v6机器上的代码:

$ qemu-system-arm -M versatilepb -cpu arm1176 -kernel math.elf -nographic -serial /dev/null -s -S
QEMU 1.7.50 monitor - type 'help' for more information
(qemu) audio: Could not init `oss' audio driver

并在gdb会话后返回正确的结果:

(gdb) target remote localhost:1234
Remote debugging using localhost:1234
0x00008104 in _start ()
(gdb) n
Single stepping until exit from function _start,
which has no line number information.
0x00009dec in memset ()
(gdb) set $pc = 0x822c
(gdb) n
8     float a = 1.25;
(gdb) n
10    float b = sinf(a);
(gdb) n
11    return 0;
(gdb) p/f $r0
$1 = 0.948984623
(gdb) 

这种情况的区别在于首先执行初始化函数,然后跳转到main函数。换句话说,scott在正确的路径上,需要一些寄存器初始化。我只是不确定它是否是VFP指令问题,因为我在ARM-v6机器上得到了正确的结果。当然,它现在也适用于ARM-v7。

看起来我需要更多地学习ARM程序集以找出必要的寄存器初始化参数。

答案 1 :(得分:0)

SP寄存器未初始化。以下是ARM程序集中的一个工作示例:

        .text
entry:  b start           
fval:   .single 0e1.25
        .align

start:  mov sp, #0x80000
        ldr r0, fval
        bl sinf 
stop:   b stop

结果在R0寄存器中。