caller: not preserved across fn call. 需要调用函数来保存寄存器。参考下面例子中的ra寄存器值。
callee: preserved across fn call. 被调用函数来保存寄存器。
根据CSAPP 3.7.1栈结构看,return address属于前一栈帧保存的,所以fp register应该指向return address的地址,即当前栈帧的顶部。一个栈帧中保存在最高位地址的是previous fp。所以这里最上面一个stack frame也应该把return address去掉。
sum_to:
mv t0, a0
li a0, 0
loop:
add a0, a0, t0
addi t0, t0, -1
bnez t0, loop
ret // 返回到li t0, 2
sum_then_double:
addi sp, sp, -16; // 分配栈空间
sd ra, 0(sp) // ra的值存入sp+0地址。caller保存sum_the_double执行完的返回地址
call sum_to // 这里调用call,ra的值被设置为下一条指令地址,即li t0, 2
li t0, 2
mul a0, a0, t0
ld ra, 0(sp) // 恢复sum_them_double的返回地址
addi sp, sp, 16
ret