参考了网上各种关于配置printf的资料,在官方发布的arm gcc上就没有能正确打印浮点数的。
翻出若干年前自己写的c库,把printf相关代码移植过来,依旧打印不出来。
但使用segger embeded studio带的gcc版本就可以,无论是它自己带的库还是我的库都正常。用MDK,IAR的编译器也是正常的。
研究了一通,发现原来是arm gcc的变长参数处理逻辑有问题。
内建的va_arg读取8字节的参数没有处理对齐,但编译器生成的调用栈是有"对齐"动作的。
为啥打引号?
因为编译器生成的调用栈并没有真的对齐内存地址,它只是按eabi的传参逻辑进行了“奇/偶”对齐
对于变长参数来说,反正是全入栈,这个奇偶对齐没有什么用处。只会让va_arg的相关逻辑失效。
这个操作还会把原本对齐到内存边界的数据搞成不对齐的。
llvm for embeded arm也有相同的毛病。
最后还是我自己写了个支持参数“对齐”的va_arg才解决问题。
这么明显的问题,在网上没见有人提过。难道是我使用gcc的姿势不对?
arm eabi的spec中也是恰到好处的缺少关于变长参数的相关约定(或者是我眼瞎没看到?)
|