最近,我正在使用在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语言库)。注意,可以正确计算浮点数/双数,正确存储在内存中,它们无法正确打印。
我认为操作系统可能有问题。我只是想知道可能是什么原因。有没有人以前遇到过这个问题?
答案 0 :(得分:5)
MIPS-EABI需要8字节堆栈对齐和您的特殊嵌入式操作系统"正在将堆栈对齐在4字节边界上。
在将double作为函数参数传递之前,似乎正常运行的应用程序是此错误的典型症状。
您需要确保操作系统创建具有8字节堆栈对齐的线程。
答案 1 :(得分:3)
你确定在newlib库的构建中为printf()输入/输出函数启用了float和double支持吗? 也许您的newlib已使用选项
进行编译- disable-newlib-io-float
--disable-newlib-IO-长双
默认为“已启用”。
[编辑]
在嵌入式世界中,许多应用程序不需要浮点/双操作。但是在libs中支持float / double需要大量的内存,这通常是一种罕见的资源。因此,如果不需要,则在stdio lib中禁用float / double的支持是一种常见做法。在IDE中,这些不支持float / double的stdio库通常称为“微小”或“小”。请检查您是否链接到newlib的这种“微小”版本。
我强烈怀疑这是你遇到问题的原因。
答案 2 :(得分:0)
我在使用ARM的Newlib上遇到了与printf("%f",some_double)相同的问题。 解决方案: 将您的堆栈声明为
unsigned long long myStackRegion[MY_STACK_SIZE / sizeof(unsigned long long)];
对于MIPS,您应该验证sizeof(unsigned long long)== 8。