本文通过一个简单的函数调用,简单记录了RV寄存器调用情况。
c代码如下:
#include "riscv_common.h"
//#define DDR0_BASE_ADDR 0x800000000
int amo_mem;
int test_nop(int param0,int* addr_param,int param1){
return param1;
}
int main() {
int a[10];
int param1;
test_nop(1000,a,param1);
return 100;
}
test_nop需要传入三个参数,返回其中一个参数。
生成汇编代码如下(部分):
00000000000027c0 <test_nop>:
27c0: 79 71 addi sp, sp, -48
27c2: 06 f4 sd ra, 40(sp)
27c4: 22 f0 sd s0, 32(sp)
27c6: 00 18 addi s0, sp, 48
27c8: 23 26 a4 fe sw a0, -20(s0)//保存传参
27cc: 23 30 b4 fe sd a1, -32(s0)//保存传参
27d0: 23 2e c4 fc sw a2, -36(s0)//保存传参
27d4: 03 25 c4 fd lw a0, -36(s0)//将第三个传参放入返回值寄存器
27d8: 02 74 ld s0, 32(sp)
27da: a2 70 ld ra, 40(sp)
27dc: 45 61 addi sp, sp, 48
27de: 82 80 ret
00000000000027e0 <main>:
27e0: 39 71 addi sp, sp, -64 //开辟栈空间64B
27e2: 06 fc sd ra, 56(sp) //保存返回寄存器
27e4: 22 f8 sd s0, 48(sp) //保存s0(fp)指针,即前一个stack frame的指针
27e6: 80 00 addi s0, sp, 64 //将s0(fp)指向当前frame的栈顶
27e8: 01 45 mv a0, zero
27ea: 23 26 a4 fe sw a0, -20(s0) //保存a矩阵指针到s0-20的地址
27ee: 03 26 04 fc lw a2, -64(s0) //保存最后一个参数param1地址
27f2: 13 05 80 3e addi a0, zero, 1000 //a0为函数参数寄存器(or返回值),传值1000
27f6: 93 05 44 fc addi a1, s0, -60 //a1位函数参数寄存器(or返回值),传址
27fa: 97 00 00 00 auipc ra, 0 //更新ra为当前pc,即27fa
27fe: e7 80 60 fc jalr -58(ra) //跳转testnop,即 'h27fa- 'd58 = 'h27c0
2802: 13 05 40 06 addi a0, zero, 100 //更新a0为100,作为返回值
2806: 42 74 ld s0, 48(sp) //恢复s0
2808: e2 70 ld ra, 56(sp) //恢复ra
280a: 21 61 addi sp, sp, 64 //恢复sp
280c: 82 80 ret
参考链接: