c - C 函数调用的 ARM 汇编函数中的寄存器使用情况

标签 c gcc arm calling-convention

ARM 的 C 函数调用约定说:

  • 调用者将传递 r0-r3 中的前 4 个参数。
  • 调用者将在堆栈上传递任何额外的参数。
  • 调用者将从 r0 获取返回值。

  • 我正在手工制作一个由 C 调用的汇编函数。原型(prototype)等价于:
    void s(void);
    
    假设一个 C 函数 c()来电s() .
    由于s()没有参数也没有返回值。我相信r0-r3编译器不会触动以生成 c() 的调用序列调用s() .
    假设 s()将使用 r0-r12来完成它的功能。 c() 也有可能将使用这些寄存器。
    我不确定我是否必须明确 保存和恢复 s() 中涉及的所有寄存器,比如说r0-r12 .这样的内存操作会花费一些时间。
    或者至少我不必为 r0-r3 这样做。 ?

    最佳答案

    来自 Procedure Call Standard for the Arm Architecture ,第 6.1.1 节(第 19 页):

    A subroutine must preserve the contents of the registers r4-r8, r10, r11 and SP (and r9 in PCS variantsthat designate r9 as v6)


    所以是的,因为 r0-r3 是暂存寄存器,所以在 s() 中使用它们之前不需要保存它们。 ,但您必须保存和恢复任何其他寄存器。
    假设编译器与 ARM ABI 兼容,则声明 s()像这样:
    extern void s(void);
    
    应该足够了,并且编译器不应发出依赖于 c() 中 r0-r3 先前值的代码。调用 s() 后的函数(即 c() 应该在调用 s() 之前保存 r0-r3 并在之后恢复它们),因为这会破坏 ABI 合规性。

    关于c - C 函数调用的 ARM 汇编函数中的寄存器使用情况,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63592851/

    相关文章:

    linux - 如何修复../libcrypto.so : undefined reference to `rc4_md5_enc' ?

    c - c语言中的memset函数

    c - 如何在 C 中#define 数组?

    linux - 用于附加字符串元数据的自定义 ELF 部分

    gcc - aarch64 : NEON registers when compiling with gcc

    Docker 错误 standard_init_linux.go :185: exec user process caused "exec format error with Qnap TS131P

    c - OpenSSL RSA-2048 未加密 block 比应有的长度长

    c++ - C/C++ 中 assert(false) 的更好替代方案

    c++ - 空默认构造函数与隐式定义的不同机器代码

    c++ - 按值调用时的隐式转换和多态性