cortex-m未声明函数导致定点浮点abi混淆出错
问题引入
开发环境:iar,平台cortex-m4,调用第三方lib里的接口但不声明函数,编译成功,但是程序运行出错。针对该问题跟踪发现这是个abi调用规则的问题。给出一个简单的例子和相关解释。
示例如下:
在a.c文件定义如下函数
void test(float a, float b, float c, float d)
{
mprintf("%f %f %f %f",a,b,c,d);
mprintf("%f %f %f %f",a,b,c,d);
mprintf("%f %f %f %f",a,b,c,d);
mprintf("%f %f %f %f",a,b,c,d);
mprintf("%f %f %f %f",a,b,c,d);
mprintf("%f %f %f %f",a,b,c,d);
mprintf("%f %f %f %f",a,b,c,d);
mprintf("%f %f %f %f",a,b,c,d);
mprintf("%f %f %f %f",a,b,c,d);
mprintf("%f %f %f %f",a,b,c,d);
mprintf("%f %f %f %f",a,b,c,d);
while(1);
}
在b.c调用该函数
test(1.0f,1.1f,1.2f,1.3f);//不声明函数
程序将无法正确打印参数
问题探究解释
调用函数汇编代码如下
被调用函数汇编代码如下:
可以看到,调用函数把参数传递放置在R0-R4寄存器,但被调用函数却从S0-S4内取出参数,因此产生错误
在b.c调用该函数前增加声明
extern void test(float a, float b, float c, float d);
test(1.0f,1.1f,1.2f,1.3f);
生成汇编代码如下:
此时输出结果正确
总结
因此,在调用lib中的接口时,务必要声明接口,注意留心编译器给出的警告。
参考
关于编译器ABI规则可以参考:https://developer.arm.com/docs/ihi0042/g/procedure-call-standard-for-the-arm-architecture-abi-2018q4-documentation