C 函数调用的 ARM 汇编函数中的寄存器使用

smw*_*dia 4 c gcc arm calling-convention

ARM 的 C 函数调用约定说:

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

我正在手工编写一个由 C 调用的汇编函数。原型相当于:

void s(void);
Run Code Online (Sandbox Code Playgroud)

假设一个 C 函数c()调用s().

因为s()没有参数也没有返回值。相信r0-r3不会被编译器碰触生成调用序列的c()to call s()

假设s()将使用r0-r12来完成其功能。也有可能c()使用这些寄存器。

我不确定是否必须明确保存和恢复所有涉及的寄存器s(),比如r0-r12。这样的内存操作会花费一些时间。

或者至少我不必这样做r0-r3

Mar*_*lli 5

来自Arm 架构的过程调用标准,第 6.1.1 节(第 19 页):

子程序必须保留寄存器 r4-r8、r10、r11 和 SP(以及将 r9 指定为 v6 的 PCS 变体中的 r9)的内容

所以是的,因为 r0-r3 是临时寄存器,您不需要在使用它们之前保存它们s(),但是您必须保存和恢复任何其他寄存器。

假设编译器符合 ARM ABI,然后声明s()如下:

extern void s(void);
Run Code Online (Sandbox Code Playgroud)

应该就足够了,并且编译器不应c()在调用后发出依赖于函数中 r0-r3 先前值的代码s()(即,c()如果需要,应在调用之前保存 r0-r3s()并在调用之后恢复它们),因为这会破坏 ABI 合规性.