【问题标题】:ARM64 calling conventions: caller or callee saved when there are fewer than 8 args?ARM64调用约定:少于8个参数时保存调用者或被调用者?
【发布时间】:2021-08-09 16:55:08
【问题描述】:

这是关于 ARM 64 位的 Unix/Linux ABI。

如果一个函数正在使用寄存器 x0-x7,因为它已收到 8 个参数,然后它调用另一个也计划使用的函数,比如说 x6-x7,是期望调用者保存这些参数还是被调用者将救他们?

Unix aarch64 ABI 对此并不清楚。

【问题讨论】:

  • 每个函数都可以覆盖 x0 到 x7,故事结束。因此,如果您的调用者在它关心的任何寄存器中有数据,它需要在调用任何其他函数之前保存它们。但我不是 100% 确定这是否是您所要求的。 “计划使用 x6-x7”令人困惑,因为您的调用者无法知道被调用者实际计划使用什么;它只知道 ABI 允许它使用什么。
  • 是的,它澄清了它。

标签: linux assembly arm64 calling-convention abi


【解决方案1】:

函数签名不影响调用约定。

无论函数是否实际占用那么多参数,所有可能的参数传递寄存器总是被调用破坏,因此调用者应将任何“宝贵”值保留在其他寄存器或内存中。

这通常是一个很好的设计。例如一个接受 2 个 args 的函数可能想要调用另一个接受更多 args 的函数,并且不想浪费指令保存/恢复其调用者的 x2 以便它可以使用它传递一个 arg。

此外,在您的假设设计中,像 printf 这样的可变参数函数必须恢复它们可能接触过的所有 arg 传递寄存器,以防它们被调用的次数更少。 (这样做比计算 args 并仅恢复 arg 列表末尾的那些更容易。只有 8 个寄存器只有四个 ldp 加载对指令。)

另外,浮点寄存器呢?大多数函数不使用 FP 参数,但如果它们想在内部调用数学函数,您不希望它们浪费指令保存/恢复它们。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-05
    • 2019-08-18
    • 2019-10-28
    • 1970-01-01
    • 1970-01-01
    • 2020-11-19
    • 2021-01-20
    • 1970-01-01
    相关资源
    最近更新 更多