temporaties are used for the right side of the calculation =
Register is 1 of 2 types:
Caller saved:
the callee funciton can use them freely
caller will need to save to mem and then load after call callees
Callee saved:
callee must save the register before modifying them and restore it before returning to caller
Procedure calls convention:
Transfer control: how to jump to callee and back to caller?
Use JAL, JALR:
caller: JAL x1, callee // store the next address to run after done w the function in x1
callee: JALR x0, 0(x1)// return to instruction in address x1
but if the callee calls another callee, then that 2nd callee will override x1
Use stack:
at the beginning of any function, push the return address to the stack
ADDI sp, sp, -4
calculate new stack pointer, only 4 for 1 address, but more is needed if argument is passed, ex: pass 2 then -12
or just -4 now and minus more later when add
SW x1, 0(sp)
store x1 in that new stack pointer
if calls a callee, Jump and Link to callee
JAL x1, callee1
x1 is now the next instruction in caller
then at the beginning of new function, push like in step 1
then the next in the stack is the address of instruction of last caller
a callee that also a caller needs to pop its return address then return to its caller:
Pop by
LW x1, 0(sp)
ADDI sp, sp, 4
then JALR x0, 0(x1)
a callee that doesnt call any other function, it only need to return to its x1 that defined at the begining of its function
JALR x0, 0(x1)
Pass arguments: how to pass value from caller to callee? ^5e5eca
Caller use register x10-x17 and callee uses it
ex: add(1,2) →
ADDI x10, x0, 1
ADDI x11, x0, 1
JAL x1, add
then the callee uses x10 and x11 in its instruction
But callee calls another callee, then x10 is overwritten, we need a way to save the variables:
use saved registers and save to stack and load it back from stack
its callee’s job to store the saved registers of its callee and load it back
If callee calls another function and doesnt use the arguments after that, there is no need to store all the arguments, only store values exist before subfunction call and needed after that function
Manage registers:
Functions are complied in isolation
Functions make use of general purpose registers
Allow each routine to use registers
Prevent routines from clobbering each others’ data