在RISC-V中,a1寄存器何时用于函数返回?



在RISC-V,a0&a1寄存器保存函数参数或返回值(如果有的话)。我注意到在生成的汇编代码中,返回值保存到a0寄存器。是否a0是返回值的默认reg,仅当返回值太大而无法单独适合a0或有多个值返回时才使用a1?

#  1 long foo(long a, unsigned long b, char *cp)
#  2 {
#  3   char c = *cp;
#  4   long sum=0;
#  5   long n = a > b ? a-b : b-a;
#  6 
#  7   do {
#  8     sum += n + c;
#  9     n--;
# 10   } while (n > 0);
# 11 
# 12   return sum;
# 13 }

.file   "example.c"
.text
.align  2
.globl  foo
foo:                            # a0 = a, a1 = b, a2 = cp
lbu     a5,0(a2)        # a5 = load byte at *c        (=c)
sub     a4,a1,a0        # a4 = b-a                    (=n, ? false, line 5)
bleu    a0,a1,.L3       # a < b ? goto .L3
sub     a4,a0,a1        # a4 = a-b                    (=n, ? true, line 5)
.L3:
add     a5,a5,a4        # a5 = c + n
li      a0,0            # a0 = 0                      (=sum, line 4)
.L4:
add     a0,a0,a5        # a0 += a5 (=c+n)             (line 8)
addi    a4,a4,-1        # a4--                        (=n--, line 9)
addi    a5,a5,-1        # a5--                        (=(c+n)--)
bgt     a4,zero,.L4     # a4(=n) > 0 ? goto .L4
ret                     # return a0(=sum)

以上是c代码和相应的objdump risc-v指令。sum最终存储在a0中,而a1用于保存b等函数参数。在这种情况下,编译器知道它只需要查看a0寄存器的返回值吗?

如果返回值sum大得多(而不是long),并且不能单独适用于a0,那么编译器是否会将sum存储在a0a1中,并参考两个寄存器的返回值?

我只是感到困惑,因为在汇编代码中没有提到返回值存储在哪里,似乎一切都发生在引擎盖下。

根据调用约定,适合两个或更少单词的返回值放在a0和a1中。隐含的,但没有直接说明的是首先使用a0,因此适合一个单词的返回值将在a0中,而a1将不使用。

最新更新