首页 > 解决方案 > 不同的函数调用程序集与 -O0 和 -O1 与 ARM 上的 GCC

问题描述

我想从 C 中调用一个汇编函数。它是调用约定的基本示例的一部分。

该功能是一个基本的:

int mult(int A, int B){
    return A*B
}

根据ARM® 体系结构的过程调用标准,参数AB应位于寄存器中r0,并r1分别用于函数调用。返回值应该在r0.

本质上,我希望该功能是:

EXPORT mult
mult MULT r0, r0, r1
     BX lr

使用 GCC 7.2.1(无)-O1 -mcpu=cortex-m4 -mabi=aapcs,我得到以下信息:(使用编译器资源管理器)

mult:
    mul     r0, r1, r0
    bx      lr

这是我所期望的。然而。如果我禁用优化(-O0),我会得到以下废话:

mult:
    push    {r7}
    sub     sp, sp, #12
    add     r7, sp, #0
    str     r0, [r7, #4]
    str     r1, [r7]
    ldr     r3, [r7, #4]
    ldr     r2, [r7]
    mul     r3, r2, r3
    mov     r0, r3
    adds    r7, r7, #12
    mov     sp, r7
    pop     {r7}
    bx      lr

这意味着 GCC 正在r7用作我认为的帧指针,并通过堆栈传递所有参数和返回值。这不是根据 AAPCS。

这是编译器资源管理器、GCC 的错误还是我错过了 AAPCS 中的某些内容?为什么 -O0 的调用约定与 AAPCS 文档中指定的调用约定完全不同?

标签: gccarmcompiler-optimizationcalling-convention

解决方案


不要费心分析为调试模式编译的机器代码,因为它们遵循一些非常模糊的序列,允许通过断点逐步执行,同时保持所有全局/局部变量可见。

如果您想要学习汇编,这不仅没有意义,而且更令人困惑。

去,-O2甚至-O3一直去。


推荐阅读