3

最近,我正在研究一个在MIPS架构上运行的特殊嵌入式操作系统。我对此知之甚少。当我使用 printf 函数时,看到一些奇怪的东西:

int a = 10;
float b = 3.14;
double c = 3.14;

printf("a is %d\n", a);           // I'm sorry I forgot to type the parameters just now
printf("b is %f\n", b);           //  Error
printf("c is %f\n", c);           //  Error

输出是:

a is 10
b is 0.000000

a是对的,但b似乎是错的,c甚至无法打印。函数 printf 来自 newlib(一个 C 语言库)。请注意,浮点数/双精度数可以正确计算,正确存储在内存中,但无法正确打印。

我认为操作系统可能有问题。我只是想知道可能是什么原因。有没有人遇到过这个问题?

4

3 回答 3

5

MIPS-EABI 需要 8 字节堆栈对齐,而您的“特殊嵌入式操作系统”将堆栈对齐 4 字节边界。

在将双精度作为函数参数传递之前,应用程序似乎可以正常运行,这是此错误的典型症状。

您需要确保操作系统创建具有 8 字节堆栈对齐的线程。

于 2013-09-11T17:32:42.020 回答
3

您确定在 newlib 库的构建中为 printf() 等输入/输出函数启用了浮点和双精度支持吗?也许您的 newlib 已使用选项编译

--disable-newlib-io-float
--disable-newlib-io-long-double

默认为“启用”。

[编辑]

在嵌入式世界中,许多应用程序不需要浮点/双精度操作。但是在库中支持 float/double 需要大量内存,这通常是一种稀有资源。因此,如果不需要,通常的做法是在 stdio 库中禁用对 float/double 的支持。在 IDE 中,这些不支持 float/double 的 stdio 库通常称为“tiny”或“small”。请检查您是否链接到您的 newlib 的这种“小”版本。
我强烈怀疑这就是你的问题的原因。

于 2013-09-11T22:40:22.717 回答
0

我在带有 ARM 的 Newlib 上的 printf("%f", some_double) 遇到了同样的问题。解决方案:将您的堆栈声明为

unsigned long long myStackRegion[MY_STACK_SIZE / sizeof(unsigned long long)];

对于 MIPS,您应该验证 sizeof(unsigned long long) == 8。

于 2013-11-01T15:37:36.587 回答