在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
存储在a0
和a1
中,并参考两个寄存器的返回值?
我只是感到困惑,因为在汇编代码中没有提到返回值存储在哪里,似乎一切都发生在引擎盖下。
根据调用约定,适合两个或更少单词的返回值放在a0和a1中。隐含的,但没有直接说明的是首先使用a0,因此适合一个单词的返回值将在a0中,而a1将不使用。