Instructions: Language of the
上一个案例的情况,称之为leaf procedure:
Procedures that do not call others are called leaf procedures.
如果互相call了,怎么办呢?
One solution is to push all the other registers that must be preserved on the stack, just as we did with the saved registers. The caller pushes any argument registers (x10–x17) or temporary registers (x5-x7 and x28-x31) that are needed after the call. The callee pushes the return address register x1 and any saved registers (x8-x9 and x18-x27) used by the callee. The stack pointer sp is adjusted to account for the number of registers placed on the stack. Upon the return, the registers are restored from memory, and the stack pointer is readjusted.
示例:
![](https://img.haomeiwen.com/i11508273/f7f10f57c8e93549.png)
解答:
The parameter variable n corresponds to the argument register x10.
首先,定义label:
fact:
压栈并存储:
addi sp, sp, -16 // adjust stack for 2 items
sd x1, 8(sp) // save the return address
sd x10, 0(sp) // save the argument n
下面进行测试并判断:
addi x5, x10, -1 // x5 = n - 1
bge x5, x0, L1 // if (n - 1) >= 0, go to L1
addi x10, x0, 1 // return 1
addi sp, sp, 16 // pop 2 items off stack
jalr x0, 0(x1) // return to caller
然后定义L1:
L1: addi x10, x10, -1 // n >= 1: argument gets (n − 1)
jal x1, fact // call fact with (n − 1)
addi x6, x10, 0 // return from jal: move result of fact (n - 1) to x6:
ld x10, 0(sp) // restore argument n
ld x1, 8(sp) // restore the return address
addi sp, sp, 16 // adjust stack pointer to pop 2 items
最后是mutiplication操作(第三章才讲到):
mul x10, x10, x6 // return n * fact (n − 1)
以及返回:
jalr x0, 0(x1) // return to the caller