寄存器指南

RISC-V a0 / x10 寄存器:第一个参数、返回值与调用约定

a0 是 RISC-V psABI 的参数寄存器之一,也是返回值常用寄存器。它不是调用后保持寄存器,所以函数调用返回后,应优先按返回值或被调用方可覆盖的值来理解。

psABI:a0-a7 是参数寄存器,a0-a1 也用于返回值。
psABI:a0 调用后不保持。
新手规则:如果旧 a0 的值调用后还要用,调用前先保存。
物理编号 x10ABI 名 a0保存责任 调用者
角色
参数/返回值
调用约定
调用者保存
先记一句
a* 属于 caller-saved,callee 可以覆盖它们。
psABI 规范依据

参数/返回值寄存器

psABI 将 a0-a7 用作参数寄存器,其中 a0-a1 也用于返回值。它们不是 callee-saved,调用后可被覆盖。

调用后保持:
RISC-V psABI integer register convention
快速理解与检索要点

a0 / x10 属于 a0-a7 参数寄存器组。psABI 规定 a0-a7 用于传参,a0-a1 也用于返回值;这些寄存器调用后不保持。

a0-a7 是参数寄存器,a0-a1 也用于返回值。
a0 调用后不保持,callee 可以覆盖。

适合什么时候用

  • - 函数调用前放置参数,a0 是 第一个 参数寄存器。
  • - a0 也属于 a0-a1 返回值寄存器组,可承载函数返回值。
  • - 按 psABI 把 a0-a7 先理解为函数参数寄存器。

什么时候不要这样用

  • - 不要默认 a* 在函数调用后仍保持原值。
  • - 跨 call 还要使用的 a* 值,应在调用前保存到 s* 或栈上。

调用前后会发生什么

1

a* 属于 caller-saved,callee 可以覆盖它们。

2

调用返回后,a0 / a1 通常要优先按返回值理解,而不是原参数。

3

如果参数超过 a0-a7,额外参数会通过栈传递。

参数传递与返回值

示例用于理解规则,不替代完整程序
addi a0, zero, 3  # 第一个参数
addi a1, zero, 4  # 第二个参数
call add2
# 返回后 a0 保存返回值

常见问题

a0 / x10 调用后还能保持原参数吗?

不能假设。a0-a7 调用后不保持,callee 可以覆盖。

哪些 a 寄存器用于返回值?

psABI 规定 a0-a1 也用于返回值。