Consider the following simple function call with parameters and return value:
f1( )
{
int x;
x = f2(111, 222); // Pass 2 parameters
}
int f2(int x, int y)
{
return(999); // Pass a return value
}
|
We use this example to determine the moment (= time) when you can pass parameters and return a value
We have discussed the basic function call + return without parameters and return values:
function f1( ) function f2( ) { +------->{ ... | ... | ... | ... | ... | ... | f2( ) ----------+ ... | ... <--------------+ ... | ... | ... V ... +------ return; } } |
The function call + return is implemented in assembler programming as follows:
f1: +----> f2: ... | ... | ... | ... | ... | ... | bl f2 ----------+ ... | ... <--------------+ ... | ... | ... V ... +------ mov pc, lr |
We will add instructions to implement (1) parameter passing and (2) return a value
Note: pay attention to the timing of these events
When can/do we pass the parameters to a function ?
f1: +----> f2: ... | ... | ... | ... | ... | ... | bl f2 ----------+ ... | ... <--------------+ ... | ... | ... V ... +------ mov pc, lr |
When can/do we pass the parameters to a function ?
f1:
+----> f2:
... | ... |
... | ... |
pass params | ... |
bl f2 ----------+ ... |
... <--------------+ ... |
... | ... V
... +------ mov pc, lr
|
Answer: it must happen before the bl f2 where we call the function !!!
(It's too late to pass parameters after the bl f2 instruction !)
When does the callee (f2( )) return a value to the caller ?
f1: +----> f2: ... | ... | ... | ... | pass params | ... | bl f2 ----------+ ... | ... <--------------+ ... | ... | ... V ... +------ mov pc, lr |
When does the callee (f2( )) return a value to the caller ?
f1: +----> f2: ... | ... | ... | ... | pass params | ... | bl f2 ----------+ ... V ... <--------------+ save return value ... | in a register ... +------ mov pc, lr |
Answer: it must happen before the callee returns to its caller !!!
When does the caller (f1( )) use the return value from the callee ?
f1:
+----> f2:
... | ... |
... | ... |
pass params | ... |
bl f2 ----------+ ... V
... <--------------+ save return value
... | in a register
... +------ mov pc, lr
|
When does the caller (f1( )) use the return value from the callee ?
f1: +----> f2: ... | ... | ... | ... | pass params | ... | bl f2 ----------+ ... V use return value <---+ save return value ... | in a register ... +------ mov pc, lr |
Answer: the return value must be used immediately after the bl instruction !!!
Example of a function call with parameters and return value:
main( )
{
int x;
x = f(111, 222); // Pass 2 parameters
}
int f(int x, int y)
{
return(999); // Pass a return value
}
|
I will write this program in assembler code
We start with the function call + return instructions:
main: +----> f: ... | ... | | ... | | ... | bl f ----------+ ... | <-----------+ ... V ... | ... +------ mov pc, lr |
The first
event was:
passing the
parameters
main passes the parameters (in r0 and r1):
main: +----> f: ... | ... | mov r0,#111 | ... | mov r1,#222 | ... | bl f ----------+ ... | <-----------+ ... V ... | ... +------ mov pc, lr |
main passes the parameters (in r0 and r1):
main:
+----> f: // note (1)
... | ... |
mov r0,#111 | ... |
mov r1,#222 | ... |
bl f ----------+ ... |
<-----------+ ... V
... |
... +------ mov pc, lr
|
Note (1): When function
f( ) starts
running, it
"sees" its
parameters in
registers r0 and r1
When f( ) finishes, it passes the return value (999) in register r0:
main:
+----> f: // note (1)
... | ... |
mov r0,#111 | ... |
mov r1,#222 | ... |
bl f ----------+ ... |
<-----------+ ... V
... | mov r0,#999
... +------ mov pc, lr
|
Note (1): When function
f( ) starts
running, it
"sees" its
parameters in
registers r0 and r1
When f( ) finishes, it passes the return value (999) in register r0:
main: +----> f: // note (1) ... | ... | mov r0,#111 | ... | mov r1,#222 | ... | bl f ----------+ ... | // note (2) <--------+ ... V ... | mov r0,#999 ... +------ mov pc, lr |
Note (1): When function
f( ) starts
running, it
"sees" its
parameters in
registers r0 and r1
Note (2): When function
f( )
returns,
main( )
"sees" the
return value in
register r0
We must use the return value in (R0) immediately after returning (here: update the variable x):
main: +----> f: // note (1) ... | ... | mov r0,#111 | ... | mov r1,#222 | ... | bl f ----------+ ... | // note (2) <--------+ ... V movw r1,#lower16:x | mov r0,#999 movt r1,#upper16:x +------ mov pc, lr str r0,[r1] |
Note (1): When function
f( ) starts
running, it
"sees" its
parameters in
registers r0 and r1
Note (2): When function
f( )
returns,
main( )
"sees" the
return value in
register r0
DEMO:
/home/cs255001/demo/asm/8-sub/skel-reg-param.s