COSC121: Computer Systems: Runtime Stack
Transcript of COSC121: Computer Systems: Runtime Stack
COSC121: Computer Systems:Runtime Stack
Jeremy Bolton, PhD
Assistant Teaching Professor
Constructed using materials:
- Patt and Patel Introduction to Computing Systems (2nd)
- Patterson and Hennessy Computer Organization and Design (4th)
**A special thanks to Rich Squier and Walid Najjar
Notes
• Read PP.10, PP.17
• Finish HW#4 and Project #2
Outline
• Overview of
– Subroutine Calls and Recursion … what could go wrong?
– The runtime stack
– Activations records
This week … our journey takes us …
I/O systemProcessor
Compiler
Operating System(Win, Linux)
Application (Browser)
Digital Design
Circuit Design
Instruction SetArchitecture
Datapath & Control
transistors
MemoryHardware
Software Assembler
COSC 120: Computer Hardware
COSC 121: Computer
SystemsCOSC 255: Operating Systems
Drivers
PP.10, PP.17Function Calls and the
Runtime Stack
Subroutines
• Recall a few concerns with subroutines that we were able to
alleviate via standardized protocols
• Can a service routine call another service routine?
– Data Preservation: Yes – must save data (either callee or caller save
protocol)
– Returning Execution Control to the Caller: Must save the “way” back! Must
save and restore R7 at each subroutine call.
• Way back is simply address of the next instruction to be executed (from the caller)
Can a service routine call another service routine?
• The way back is “over-written” with more than one subroutine call.
• All but the last “way” back is clobbered!
• Can we fix this?
Can a service routine call another service routine?
• Solution: Save
R7 before jump
and restore just
after return
Can we implement recursive subroutines?:What could go wrong? …
• Observe local variables are preserved locally in a subroutine, thus preserving data when control is handed to a callee.
• What happens if a subroutine calls itself …
Recursion Concerns
• Observe: Subroutines exist in 1 place in memory. Thus there is
one location in memory dedicated to each local variable, (and way
back)
– When local variables change during the course of recursive call, the local
variables values are overwritten -- thus not recoverable
– When the way back is saved/written to tempR7 during each call, it
overwrites the previous calls way back.
– Note: We avoided this issue previously because when subroutines call
different subroutines, the different subroutines do not coincide in memory.
Example Recursive Sum
sum_n(1,n) n + sum_n(1, n-1)
Recursion
Save Protocol Overwrites since
memory location is shared between
each function calls
What happens: PennSim?
PennSim: recursiveSum … What Happens?
Recursion Concern
• There is only one instance of each subroutine in code
– It exists in one location in memory
• All recursive calls will overwrite previous local variables along the
function call chain.
Local Variables:Conceptual Diagram of Function Call Chain
int f(int i){int j = 10;return g(i + 10 * j);}
int g(int k){return p(k + 5);}
int p(int z){cout << z;return z - 1;}
int main(){ f(2); return 0; }
Local Variables in Recursion:Conceptual Diagram
int f(int n)
{
// Assumes n is non-negative
int val = 1;
if (n == 0 || n == 1) // Base case -- stop repetition
return 1;
else // recursive case -- continue recursive call
return n * f(n - 1);
}
void main()
{f(3);}
Local Variable and Recursion
• Recursion can be implemented if we maintain multiple instances
of local variables – thus saving the local variables values at each
node of the function call chain.
• How can we manage all of these instances of local variables?
• Notice a function call chain behaves much like a stack.
10-17
Stacks
• A LIFO (last-in first-out) storage structure.– The first thing you put in is the last thing you take
out.
– The last thing you put in is the first thing you take out.
• This means of access is what defines a stack,not the specific implementation.
• Two main operations:PUSH: add an item to the stack
• POP: remove an item from the stack
10-18
A Physical Stack
• Coin organizer Example …
• First quarter out is the last quarter in.
1995 1996
1998
1982
1995
1998
1982
1995
Initial State AfterOne Push
After Three More Pushes
AfterOne Pop
10-19
A Software Implementation
• The base of the stack is a “reserved” place in memory. The TOP
of the stack moves up and down when push and pop.
/ / / / / /
/ / / / / /
/ / / / / /
/ / / / / /
/ / / / / / TOP
/ / / / / /
/ / / / / /
/ / / / / /
#18
/ / / / / /
TOP
#12
#5
#31
#18
/ / / / / /
TOP #12
#5
#31
#18
/ / / / / /
TOP
Initial State AfterOne Push
After Three More Pushes
AfterTwo Pops
x4000 x3FFF x3FFC x3FFER6 R6 R6 R6
By convention, R6 holds the Top of Stack (TOS) pointer.
10-20
Basic Push and Pop Code
• For our implementation, stack grows downward(when item added, TOS moves closer to 0)
• Push
• ADD R6, R6, #-1 ; decrement stack ptrSTR R0, R6, #0 ; store data (R0)
• Pop
• LDR R0, R6, #0 ; load data from TOSADD R6, R6, #1 ; decrement stack ptr
PP Memory Map
Code and Data are generally kept in separate sections of
memory.
Variable Allocation:
Global or Static
Dynamic Sized (or other heap)
Local
17-21
Detailed Example: Fibonacci Numbers
• Mathematical Definition:
• In other words, the n-th Fibonacci number is
the sum of the previous two Fibonacci numbers.
1)0(
1)1(
)2()1()(
f
f
nfnfnf
17-22
Fibonacci: C Code
• int Fibonacci(int n)
{
if ((n == 0) || (n == 1))
return 1;
else
return Fibonacci(n-1) + Fibonacci(n-2);
}
17-23
Activation Records
• Whenever Fibonacci is invoked,
a new activation record is pushed onto the stack.
Fib(1)
R6
Fib(2)
Fib(3)
main
main calls Fibonacci(3)
Fibonacci(3) calls Fibonacci(2)
Fibonacci(2) calls Fibonacci(1)
R6
Fib(3)
main
R6
Fib(2)
Fib(3)
main
17-24
Activation Records (cont.)
Fibonacci(1) returns,Fibonacci(2) calls Fibonacci(0)
Fibonacci(2) returns,Fibonacci(3) calls Fibonacci(1)
Fibonacci(3)returns
R6
main
R6
Fib(1)
Fib(3)
main
Fib(0)
R6
Fib(2)
Fib(3)
main
17-25
Fibonacci: LC-3 Code
• Activation Record
temp
dynamic link
return address
return value
n
bookkeeping
arg
Assembly Programmer (or Compiler) generatestemporary variable to hold result of first Fibonacci call.
local
return Fibonacci(n-1) + Fibonacci(n-2);
17-26
LC-2 Code (part 1 of 3)
• Fibonacci ADD R6, R6, #-2 ; skip ret val, push ret addr
STR R7, R6, #0
ADD R6, R6, #-1 ; push dynamic link
STR R5, R6, #0
ADD R5, R6, #-1 ; set frame pointer
ADD R6, R6, #-2 ; space for locals and temps
LDR R0, R5, #4 ; load n
BRz FIB_BASE ; check for terminal cases
ADD R0, R0, #-1
BRz FIB_BASE
17-27
LC-3 Code (part 2 of 3)
•
LDR R0, R5, #4 ; read parameter n
ADD R0, R0, #-1 ; calculate n-1
ADD R6, R6, #-1 ; push n-1
STR R0, R6, #0
JSR Fibonacci ; call self
• LDR R0, R6, #0 ; pop return value
ADD R6, R6, #1
STR R0, R5, #-1 ; store in temp
LDR R0, R5, #4 ; read parameter n
ADD R0, R0, #-2 ; calculate n-2
ADD R6, R6, #-1 ; push n-2
STR R0, R6, #0
JSR Fibonacci ; call self
17-28
LC-3 Code (part 3 of 3)
•
LDR R0, R6, #0 ; pop return value
ADD R6, R6, #1
LDR R1, R5, #-1 ; read temp
ADD R0, R0, R1 ; Fibonacci(n-1) + Fibonacci(n-2)
BRnzp FIB_END ; all done
FIB_BASE AND R0, R0, #0 ; base case – return 1
ADD R0, R0, #1
FIB_END STR R0, R5, #3 ; write return value (R0)
ADD R6, R5, #1 ; pop local variables
LDR R5, R6, #0 ; pop dynamic link
ADD R6, R6, #1
LDR R7, R6, #0 ; pop return address
ADD R6, R6, #1
RET