You are on page 1of 16

Topic V0B

Procedure Calls, Stack,


and Memory Layout
A word about
naming…
Callable
Procedure Unit
Function “Pure functions” have no side effect
See “functional programming languages”
Routine

Subroutine

Subprogram

Method Methods are usually associated with objects


See “object-oriented programming languages”
1: void foo()
2: {
3: int a, b;
Procedure
4: scanf(“%d %d”, &a, &b);
5: …
Calls
6: r = bar(a, b); 1: int bar(int x, int y)
7: t = 2 * r; 2: {
8: … 3: int i, p, t;
9: r = bar(b, a); 4: t = 1;
10: c = c + 4 * r; 5: for(i = 0 ; i<y ; i++){
11: … 6: t = baz(x);
12: } 7: p = p * t; 1: int baz(int d)
8: } 2: {
9: return p; 3: int z;
10: } 4: z = 100 – d;
5: return z;
6: }
must remember
caller
1: void foo() return address
2: {
3: int a, b;
Procedure
4: scanf(“%d %d”, &a, &b);
5: …
Calls
caller
callee
6: r = bar(a, b); 1: int bar(int x, int y)
7: t = 2 * r; 2: {
8: … 3: int i, p, t;
9: r = bar(b, a); 4: t = 1;
10: c = c + 4 * r; 5: for(i = 0 ; i<y ; i++){
11: … 6: t = baz(x); callee
12: } 7: p = p * t; 1: int baz(int d)
8: } 2: {
return address 9: return p; 3: int z;
return address 10: } 4: z = 100 – d;
5: return z;
must return to correct 6: }
return address return address
1: void foo()
2: {
write return
address into ra
Problem
3: int a, b; In RISC-V there is a single register,
4: scanf(“%d %d”, &a, &b); ra, to store the return address
5: …
6: r = bar(a, b); 1: int bar(int x, int y)
7: t = 2 * r; 2: { overwrite return
8: … 3: int i, p, t; address into ra
9: r = bar(b, a); 4: t = 1;
10: c = c + 4 * r; 5: for(i = 0 ; i<y ; i++){
11: … 6: t = baz(x);
12: } 7: p = p * t; 1: int baz(int d)
8: } 2: {
9: return p; 3: int z;
10: } 4: z = 100 – d;
return to 5: return z;
return to 6: }
wrong address
correct address
Solutio
n
We need to save the value of ra somewhere

Where?

Into a stack
What Goes Into the
Stack Stack

The value of register fp

The value of register ra


(if the function calls another function)

Registers that are modified by the function

Local variables that need memory storage


Where is the Top of the
Stack?
sp 0x7FFF FFFC
Address Stack
0x7FFF FFFC
0x7FFF FFF8
RISC-V has a special register called
0x7FFF FFF4
stack pointer (sp)
0x7FFF FFF0
sp always contains the address of 0x7FFF FFEC
the top of the stack 0x7FFF FFE8
0x7FFF FFE4
0x7FFF FFE0
Saving Registers Into the
Stack Memory addresses
The stack grows towards lower memory
↑ High Address
sp
Situation: a procedure will write on s0 and call
another subroutine
s0 0x0000 0003
fp 0x7FFF FFFC Must save values of s0, fp, and ra into the
sp 0x7FFF FFF8 stack
ra 0x0040 0008
How do we make room in the stack for these
three registers?
↓ Low Address
Saving Registers Into the
Stack Memory
↑ High Address
sp
0x7FFF FFFC We need to decrement the value of sp by
s0 0x0000 0003 0x0000 0003
12
fp 0x7FFF FFFC
0x0040 0008 How do we actually ‘save’ s0, fp, and
sp 0x7FFF FFEC
FFF8
ra?
ra 0x0040 0008
Write their values, using the sw
instruction, to the stack:
↓ Low Address sw s0, 4(sp)
1: void foo()
2: {
write return
address into ra Procedure
save ra
3: int a, b;
4: scanf(“%d %d”, &a, &b);
into stack
Calls
In RISC-V there is a single register,
ra, to store the return address

5: …
6: r = bar(a, b); 1: int bar(int x, int y)
safe to
7: t = 2 * r; 2: { overwrite return
8: … 3: int i, p, t; address into ra
9: r = bar(b, a); 4: t = 1;
10: c = c + 4 * r; 5: for(i = 0 ; i <x ; i++){
11: … 6: t = baz(x);
12: } 7: p = p * t; 1: int baz(int d)
return to 8: } 2: {
correct address 9: return p; 3: int z;
10: } 4: z = 100 – d;
restore ra 5: return z;
return to
from stack
correct address
6: }
Saving Registers Into the
Stack Memory execution it is time to return to the caller
Now that the procedure has completed its
↑ High Address

How do we ‘restore’ the value of s0, fp,


0x7FFF FFFC
and ra?
s0 0x0000 01F7
0003 0x0000 0003
fp 0x7FFF FFF4
FFFC sp 0x0040 0008 Read their values, using the lw instruction,
sp 0x7FFF FFEC
FFF8 from the stack
ra 0008
0x0040 0488
Do we need to do anything to the value of
sp?
↓ Low Address
Yes, we need to increment the value of sp
by 12
Memory
Layout
Text: program code (instructions) sp 7FFF FFFChex

Static data: global variables


e.g. variables in C, constant arrays and
strings
gp initialized to address allowing ±
offsets into this segment
gp 1000 8000hex
1000 0000hex
Dynamic data: heap
e.g. malloc in C, new in Java pc 0040 0000hex

0
Stack: automatic storage
Memory
Layout
Text: program code (instructions) sp 7FFF FFFChex

Static data: global variables


e.g. variables in C, constant arrays and
strings
gp initialized to address allowing ±
offsets into this segment
gp 1000 8000hex
1000 0000hex
Dynamic data: heap
e.g. malloc in C, new in Java pc 0040 0000hex

0
Stack: automatic storage
Recap

You might also like