2 4 SubroutineCalls-A
2 4 SubroutineCalls-A
●
Subroutine Return
– jump-and-link register (jalr)
jalr
jalr rd,
rd, imm(rs1)
imm(rs1)
rd=PC+4;
rd=PC+4; PC=rs1+imm;
PC=rs1+imm;
Subroutines in RISC-V
●
Subroutine Call jal
jal x1,
x1, proc_label
proc_label
●
Subroutine Return
– jump-and-link register (jalr)
jalr
jalr x0,
x0, 0(x1)
0(x1)
x0=PC+4;
x0=PC+4; PC=x1+0;
PC=x1+0;
Subroutines in RISC-V
●
Subroutine Call jal
jal x1,
x1, proc_label
proc_label
●
Subroutine Return
– jump-and-link register (jalr)
– jalr x0, 0(x1)
●
jalr branches to the address in x1
jal, jalr – Function Call & Return
●
Caller puts the parameter values in x10 – x17 (a0 –
a7)
●
jal x1, X
– to branch to procedure X
– X is the callee
●
Callee performs the calculations, places results in a0
– a7
●
Returns control to the caller using jalr x0, 0(x1)
Subroutines in RISC-V
# main program
....
0x0FC ....
0x100 jal x1, func1
0x104 ....
....
....
Caller
Caller
Subroutines in RISC-V
# main program
....
0x0FC ....
0x100 jal x1, func1
0x104 ....
....
....
Caller
Caller
PC 0x104
0x104
Subroutines in RISC-V
Caller
Caller PC 0x104
0x104
Subroutines in RISC-V
Caller
Caller PC 0x104
0x104
x1 0x104
0x104
Subroutines in RISC-V
Caller
Caller PC 0x200
0x200
x1 0x104
0x104
Subroutines in RISC-V
Caller
Caller PC 0x240
0x240
x1 0x104
0x104
x0 0x0
0x0
Subroutines in RISC-V
Caller
Caller PC 0x104
0x104
x1 0x104
0x104
x0 0x0
0x0
Subroutines in RISC-V
Caller
Caller PC 0x104
0x104
x1 0x104
0x104
x0 0x0
0x0
Registers Usage Convention
Call Sequence
●
Caller puts arguments in x10–x17
Call Sequence
●
Caller puts arguments in x10–x17
●
jal x1, proc_label
– proc_label is the callee
Call Sequence
●
Caller puts arguments in x10–x17
●
jal x1, proc_label
– proc_label is the callee
●
Callee performs the calculations, places the results in
the x10–x17
Call Sequence
●
Caller puts arguments in x10–x17
●
jal x1, proc_label
– proc_label is the callee
●
Callee performs the calculations, places the results in
the x10–x17
●
Callee returns control to the caller
– jalr x0, 0(x1)
Subroutines – Parameter Passing
##main
mainprogram
program 0x200 func1:
func1:
....
.... ....
....
....
.... ....
....
add
addx10,
x10,x0,
x0,x8
x8 0x240 jalr
jalrx0,
x0,0(x1)
0(x1)
add
addx11,
x11,x0,
x0,x9
x9
jal
jalx1,
x1,func1
func1
....
....
....
....
....
....
Subroutines – Parameter Passing
●
Caller saves arguments in x10 – x17
Subroutines – Parameter Passing
●
Caller saves arguments in x10 – x17
●
Callee saves results to return in x10 – x17
Subroutines – Parameter Passing
●
Caller saves arguments in x10 – x17
●
Callee saves results to return in x10 – x17
●
How to pass more than 8 args?
Subroutines – Parameter Passing
●
Caller saves arguments in x10 – x17
●
Callee saves results to return in x10 – x17
●
How to pass more than 8 args?
●
Program stack
Subroutines – Parameter Passing
●
Caller saves parameters in $a0 - $a3
●
Callee stores results in $v0, $v1.
●
How does the caller pass more than 4
parameters to the callee?
●
Program stack
The RISC-V Stack
STACK
0xF0 71
0xE8 94
sp 0xE0 10
0xD8 ...
...
...
...
...
...
...
...
...
x2 (sp) 0x3F
0x3FFFFF
FFFFFFE0
FFE0
The RISC-V Stack
STACK
0xF0 71
0xE8 94
sp 0xE0 10
0xD8 ...
...
...
...
...
...
...
...
... ●
Push the value in x5
on the stack
x2 (sp) 0x3F
0x3FFFFF
FFFFFFE0
FFE0
The RISC-V Stack
STACK
0xF0 71
0xE8 94
sp 0xE0 10
0xD8 ...
Push
Push
... addi x2, x2, -8
sd x5, 0(x2)
...
...
...
...
...
...
... ●
Push the value in x5
on the stack
x2 (sp) 0x3F
0x3FFFFF
FFFFFFE0
FFE0
The RISC-V Stack
STACK
0xF0 71
0xE8 94
0xE0 10
sp 0xD8 9999
...
Push
Push
... addi x2, x2, -8
sd x5, 0(x2)
...
...
...
...
...
...
... ●
Push the value in x5
on the stack
x2 (sp) 0x3F
0x3FFFFF
FFFFFFD8
FFD8
The RISC-V Stack
STACK ●
Pop into x6
0xF0 71
0xE8 94
0xE0 10
sp 0xD8 9999
...
...
...
...
...
...
...
...
...
x2 (sp) 0x3F
0x3FFFFF
FFFFFFD8
FFD8
The RISC-V Stack
STACK ●
Pop into x6
0xF0 71
0xE8 94
0xE0 10
sp 0xD8 9999
...
Pop
Pop
ld x6, 0(x2)
...
... addi x2, x2, 8
...
...
...
...
...
...
x2 (sp) 0x3F
0x3FFFFF
FFFFFFD8
FFD8
The RISC-V Stack
STACK ●
Pop into x6
0xF0 71
0xE8 94
sp 0xE0 10
0xD8 9999
...
Pop
Pop
ld x6, 0(x2)
...
... addi x2, x2, 8
...
...
...
...
...
...
x2 (sp) 0x3F
0x3FFFFF
FFFFFFE0
FFE0
Subroutines – Parameter Passing
# main program Before
Beforeparameters
parameterspushed
pushed
# 10 parameters to func1
.... ...
.... ...
... sp
jal x1, func1
....
...
....
....
...
...
...
Subroutines – Parameter Passing
# main program Before
Beforeparameters
parameterspushed
pushed
# 10 parameters to func1
.... ...
.... ...
# 8 args in x10 – x17 sp
...
# push 2 on stack
...
...
...
jal x1, func1 ...
....
....
....
...
...
Subroutines – Parameter Passing
# main program Before
Beforeparameters
parameterspushed
pushed
# 10 parameters to func1
.... ...
.... ...
# 8 args in x10 – x17 sp
...
# push 2 on stack
...
addi sp, sp, -16
sw x5, 0(sp)
sw x6, 8(sp) ...
jal x1, func1
....
....
...
....
...
Subroutines – Parameter Passing
# main program After
Afterparameters
parameterspushed
pushed
# 10 parameters to func1
.... ...
.... ...
# 8 args in x10 – x17
...
x6
# push 2 on stack
...
addi sp, sp, -16 sp x5
sw x5, 0(sp)
sw x6, 8(sp) ...
jal x1, func1
....
....
...
....
...
Subroutines – Parameter Passing
# main program After
Afterparameters
parameterspushed
pushed
# 10 parameters to func1
.... ...
.... ...
# 8 args in x10 – x17
...
x6
# push 2 on stack
...
addi sp, sp, -16 sp x5
sw x5, 0(sp)
sw x6, 8(sp) ...
jal x1, func1
....
.... func1:
.... ...
....
lw x28, 0(sp) ...
lw x29, 8(sp)
....
....
Nested Subroutines
# main program
.... func1:
.... ....
jal x1, func1 jal x1, func2
.... ....
.... jalr x0, 0(x1)
....
Nested Subroutines
# main program
.... func1:
.... ....
jal x1, func1 jal x1, func2
.... ....
.... jalr x0, 0(x1)
....
Stores
Storesreturn
returnaddress
addressin
inx1
x1
Nested Subroutines
# main program
.... func1:
.... ....
jal x1, func1 jal x1, func2
.... ....
.... jalr x0, 0(x1)
....
func2:
....
....
jalr x0, 0(x1)
Stores
Storesreturn
returnaddress
addressin
inx1
x1
Nested Subroutines
Stores
Storesreturn
returnaddress
addressin
inx1
x1
# main program
.... func1:
.... ....
jal x1, func1 jal x1, func2
.... ....
.... jalr x0, 0(x1)
....
func2:
....
....
jalr x0, 0(x1)
Stores
Storesreturn
returnaddress
addressin
inx1
x1
Nested Subroutines
●
func1 overwrites return address in x1
Nested Subroutines
●
func1 overwrites return address in x1
●
Store the current return address in the program
stack
Nested Subroutines
func1: Stack
Stackbefore
beforefunc1
func1is
iscalled
called
....
.... ...
.... ...
x6
...
sp x5
...
...
...
Nested Subroutines
func1: In
Infunc1
func1
addi x2, x2, -8
sd x1, 0(x2) # push ra on stack ...
.... ...
x6
...
sp x5
...
...
...
Nested Subroutines
func1: func1
func1––push
pushra
rato
tostack
stack
addi x2, x2, -8
sd x1, 0(x2) # push ra on stack ...
.... ...
x6
...
x5
sp x1
...
...
...
Nested Subroutines
func1: func1
func1––push
pushra
rato
tostack
stack
addi x2, x2, -8
sd x1, 0(x2) # push ra on stack ...
.... ...
x6
...
x5
sp x1
...
Show
Showthe
thestack afterfunc1
stackafter func1
...
passes
passes x5x5as
asargument
argumenttotofunc2
func2
...
and callsfunc2?
andcalls func2?
Show
Showthe
thecode
codechanges
changesininfunc1
func1
andfunc2.
and func2.
Nested Subroutines
func1: func1
func1––push
pushra
rato
tostack
stack
addi x2, x2, -8
sd x1, 0(x2) # push ra on stack ...
.... ...
# push x5 to stack
addi x2, x2, -8
sd x5, 0(x2) x6
...
jalr x1, func2 x5
sp x1
...
Show
Showthe
thestack afterfunc1
stackafter func1
...
passes
passes x5x5as
asargument
argumenttotofunc2
func2
...
and callsfunc2?
andcalls func2?
Show
Showthe
thecode
codechanges
changesininfunc1
func1
andfunc2.
and func2.
Nested Subroutines
func1: func1
func1––push
pushra
rato
tostack
stack
addi x2, x2, -8
sd x1, 0(x2) # push ra on stack ...
.... ...
# push x5 to stack
addi x2, x2, -8
sd x5, 0(x2) x6
...
jalr x1, func2 x5
... x1 (ra-f1)
sp x5
...
Show
Showthe
thestack afterfunc1
stackafter func1
...
passes
passes x5x5as
asargument
argumenttotofunc2
func2
...
and callsfunc2?
andcalls func2?
Show
Showthe
thecode
codechanges
changesininfunc1
func1
andfunc2.
and func2.
Nested Subroutines
func1: func2
func2entered
entered
addi x2, x2, -8
sd x1, 0(x2) # push ra on stack ...
.... ...
# push x5 to stack
addi x2, x2, -8
sd x5, 0(x2) x6
...
jalr x1, func2 x5
... x1 (ra-f1)
sp x5
...
func2:
addi x2, x2, -8
sd x1, 0(x2) ...
.... ...
Nested Subroutines
func1: func2
func2pushes
pushesra
rato
tostack
stack
addi x2, x2, -8
sd x1, 0(x2) # push ra on stack ...
.... ...
# push x5 to stack
addi x2, x2, -8
sd x5, 0(x2) x6
...
jalr x1, func2 x5
... x1 (ra-f1)
x5
...
sp x1 (ra-f2)
func2:
addi x2, x2, -8
sd x1, 0(x2) ...
.... ...
Stack Frame
caller
Frame
$t0
$ra func1
Frame
fp
func2
Frame
sp
Stack Frame
●
Stack Frame: Private
space for a subroutine caller
Frame
allocated on entry and
deallocated on exit
●
Identified by a Frame $t0
$ra func1
Pointer (fp (x8)) Frame
fp
func2
Frame
sp
Stack Frame
Stack
StackFrame
Frame
fp Return Addr
Old FP
$t0
Saved $ra func1
Registers
Frame
Local
Variables fp
func2
Frame
Parameters
passed to
func2 sp
sp
Stack Frame
Stack
StackFrame
Frame
fp Return Addr In
Incase
casecallee
calleecalls
callsanother
another
Old FP
Saved
Registers
Local
Variables
Parameters
passed to
func2
sp
Stack Frame
Stack
StackFrame
Frame
fp Return Addr In
Incase
casecallee
calleecalls
callsanother
another
Old FP
Saved In
Registers Incase
casecallee
calleemodifies
modifies
Saved
SavedRegisters:
Registers:x8-x9,
x8-x9,x18-x27
x18-x27
Local
Variables
Parameters
passed to
func2
sp
Stack Frame
Stack
StackFrame
Frame
fp Return Addr In
Incase
casecallee
calleecalls
callsanother
another
Old FP
Saved In
Registers Incase
casecallee
calleemodifies
modifies
Local Local
Variables Localvariables
variablesin
incallee
callee
Parameters
passed to
func2
sp
Stack Frame
Stack
StackFrame
Frame
fp Return Addr In
Incase
casecallee
calleecalls
callsanother
another
Old FP
Saved In
Registers Incase
casecallee
calleemodifies
modifies
Local Local
Variables Localvariables
variablesin
incallee
callee
Parameters
passed to Passes
Passesargs
argsto
toanother
anotherfunc
func
func2
sp
Stack Frame
Stack
StackFrame
Frame
fp Return Addr
Old FP
...
Saved
Registers $t0
$t0
fp x1
x1
x8
x8
Local x18
Variables x18
x21
x21
func1_X
func1_X
Parameters func1_Y
sp ...
func1_Y
...
passed to
func2 ...
sp
Frame Pointer Before
Beforethe
thecall
call
...
●
After entry into a fp
subroutine:
x10
sp x11
$t0
...
...
Frame Pointer Before
Beforethe
thecall
call
...
●
After entry into a fp
subroutine:
– Save return address
x10
sp x11
$t0
...
...
Frame Pointer Before
Beforethe
thecall
call
...
●
After entry into a fp
subroutine:
– Save return address
– Save frame pointer of x10
the caller function sp x11
$t0
...
...
Frame Pointer Before
Beforethe
thecall
call
...
●
After entry into a fp
subroutine:
– Save return address
– Save frame pointer of x10
the caller function sp x11
$t0
...
...
Frame Pointer callee
calleeprologue
prologue
...
●
After entry into a fp
subroutine:
– Save return address
x10
addi x2, x2, -8 x11
$t0
sw x1, 0(x2)
sp x1
...
...
Frame Pointer callee
calleeprologue
prologue
...
●
After entry into a fp
subroutine:
– Save return address
– Save frame pointer of x10
the caller function x11
$t0
sp x1
...
...
Frame Pointer callee
calleeprologue
prologue
...
●
After entry into a fp
subroutine:
– Save return address
– Save frame pointer of x10 (a1)
the caller function x11
$t0
(a2)
x1 (ra)
addi sp
addix2,
x2,x2,
x2,-8
-8 x8 (fp)
sw
swx8,
x8,0(x2)
0(x2)
...
...
Frame Pointer callee
calleeprologue
prologue
...
●
After entry into a
subroutine:
– Save return address
– Save frame pointer of x10 (a1)
the caller function x11
$t0
(a2)
fp x1 (ra)
– Point the frame sp x8 (fp)
pointer to the first
location of stack
frame of the current ...
subroutine ...
Frame Pointer callee
calleeprologue
prologue
...
●
After entry into a
subroutine:
– Save return address
– Save frame pointer of x10 (a1)
the caller function x11
$t0
(a2)
fp x1 (ra)
– Point the frame sp x8 (fp)
pointer to the first
location of stack
frame of the current ...
subroutine ...
addi
addix8,
x8,x1,
x1,88
Frame Pointer callee
calleeprologue
prologue
...
func1:
func1:
addi
addix2,
x2,x2,
x2,-8
-8
sw
swx1,
x1,0(x2)
0(x2)
addi x10 (a1)
addix2,
x2,x2,
x2,-8
-8
sw
swx8,
x8,0(x2)
0(x2) x11
$t0
(a2)
addi
addix8,
x8,x1,
x1,88 fp x1 (ra)
...
... sp x8 (fp)
...
...
...
...
Frame Pointer callee
calleeprologue
prologue
...
func1:
func1:
addi
addix2,
x2,x2,
x2,-8
-8
sw
swx1,
x1,0(x2)
0(x2)
addi x10 (a1)
addix2,
x2,x2,
x2,-8
-8
sw
swx8,
x8,0(x2)
0(x2) x11
$t0
(a2)
addi
addix8,
x8,x1,
x1,88 fp x1 (ra)
...
... sp x8 (fp)
...
...
...
...
Parameters
Parameterscancanbebe
accessed
accessedin inthe
the
callee
calleefunction:
function:
8(x8),
8(x8),16(x8)
16(x8)
Stack Frame
callee
calleeprologue
prologue
...
●
Save change
registers
x10 (a1)
x11
$t0
(a2)
fp x1 (ra)
x8 (fp)
x12
sp x13
...
...
Stack Frame
callee
calleeprologue
prologue
...
●
Save change
registers
addi
addix2,
x2,x2,
x2,-16
-16
sw
swx12,
x12,8(x2)
8(x2) x10 (a1)
sw
swx13,
x13,0(x2)
0(x2)
x11
$t0
(a2)
fp x1 (ra)
x8 (fp)
x12
sp x13
...
...
Stack Frame
callee
calleeprologue
prologue
...
func1:
func1:
addi
addix2,x2,x2,
x2,-8
-8
sw
swx1,x1,0(x2)
0(x2)
addi
addix2,x2,x2,
x2,-8
-8
sw
swx8,x8,0(x2)
0(x2)
addi
addix8,x8,x1,
x1,88 x10 (a1)
addi
addix2,x2,x2,
x2,-16
-16 x11
$t0
(a2)
sw
swx12,
x12,8(x2)
8(x2) fp x1 (ra)
sw
swx13,
x13,0(x2)
0(x2)
##prologue x8 (fp)
prologueends
ends
...
... x12
...
... sp x13
...
...
Stack Frame
Stack
Stackbefore
beforecallee
calleereturns
returns Stack
... Stackcaller
callerexpects
expects
...
fp
x10 (a1)
x10 (a1)
x11
$t0
(a2)
sp x11$t0
(a2)
fp x1 (ra)
x8 (fp)
x12
sp x13
...
...
...
Stack Frame – Callee Epilogue
callee
calleeepilogue
●
Before return from epilogue
...
callee subroutine:
– Restore saved regs
– Restore frame pointer
of the caller function x10 (a1)
x11
$t0
(a2)
– Restore return address fp x1 (ra)
– Return x8 (fp)
x12
sp x13
...
...
Stack Frame – Callee Epilogue
callee
calleeepilogue
●
Before return from epilogue
...
callee subroutine:
– Restore saved regs
– Restore frame pointer
of the caller function x10 (a1)
x11
$t0
(a2)
– Restore return address fp x1 (ra)
– Return x8 (fp)
...
... x12
ld
ldx13,
x13,0(x2)
0(x2)
ld sp x13
ldx12,
x12,8(x2)
8(x2)
ld
ldx8,
x8,16(x2)
16(x2) ...
ld
ldx1,
x1,24(x2)
24(x2) ...
addi
addix2,
x2,x2,
x2,-32
-32
jalr
jalrx0,
x0,0(x1)
0(x1)
Stack Frame – Callee Epilogue
callee
calleeepilogue
●
Before return from epilogue
...
callee subroutine: fp
Stack
StackFrame
Frame
fp Return Addr
Old FP
$t0
$ra func1
Saved Frame
Registers
fp
func2
Local
Frame
Variables
sp
sp
Saved Registers
●
Registers 16 – 23 are saved across function
calls
Saved Registers
●
Registers 16 – 23 are saved across function
calls
●
Save registers $s0 - $s7 if used by the callee
●
Example: $s0, $s1 are saved
Stack Frame
...
●
Local variables are
allocated on the stack after
the saved registers
$t1
$t0
fp $ra
fp
$s0
$s1
func1_X
sp func1_Y
...
...
Stack Frame
Subroutines – Parameter Passing
# main program
....
.... accArray:
add $a0, $zero, $s0 add $v0, $zero, $zero
add $a1, $zero, $s1 loop:
jal accArray beq $a0, $zero, done
print $v0 lw $t0, 0($a1)
.... add $v0, $v0, $t0
.... addiu $a1, $a1, 4
.... addi $a0, $a0, -1
j loop
done:
jalr x0, 0(x1)