How Your Code Executes: A Guide to Stack Frames and Function Calls
Exploring the Low-Level Mechanics of Caller and Callee Stack Frames with a Simple Code Example
Understanding Stack Frames in Function Calls
When a program executes, it uses a stack to manage function calls and local variables. The stack is a Last-In-First-Out (LIFO) data structure that grows downwards in memory. Each function call creates a stack frame (also known as an activation record) that contains information about the function's execution, such as local variables, return addresses, and arguments.
Stack Frame Layout
The image describes the layout of two stack frames: one for the caller (the function that makes the call) and one for the callee (the function being called). Here's a detailed breakdown of the components:
Caller's Stack Frame:
Save Args: The caller saves the arguments it will pass to the callee.
argn: The nth argument passed to the callee.
Call Function: The instruction to call the callee function.
Return Address: The address to which the callee should return after execution.
Old Frame Pointer (Fp): The caller's frame pointer is saved to restore it after the callee returns.
Update Stack Pointer (Sp): The stack pointer is updated to point to the new top of the stack.
Callee's Stack Frame:
Compute Frame Size: The callee calculates the size needed for its local variables.
Local Variables: Space allocated for the callee's local variables.
Save Old Frame Pointer (Fp): The callee saves the caller's frame pointer.
Update Frame Pointer (Fp): The callee updates the frame pointer to point to its stack frame.
Update Stack Pointer (Sp): The stack pointer is updated to reflect the new top of the stack.
Return Address: The address to return to after the callee finishes execution.
Basic Code Example
Let's consider a simple C code example to illustrate this:
#include <stdio.h>
void callee(int b) {
int y = b + 1;
printf("Value of y: %d\n", y);
}
void caller() {
int a = 5;
callee(a);
}
int main() {
caller();
return 0;
}Step-by-Step Execution
Main Function:
maincallscaller.
Caller Function:
callersets up its stack frame.It saves the argument
a = 5to pass tocallee.It saves the return address to return to
mainaftercalleefinishes.It updates the stack pointer and frame pointer.
It calls
callee.
Callee Function:
calleesets up its stack frame.It saves the old frame pointer from
caller.It updates the frame pointer to point to its own frame.
It allocates space for its local variable
y.It computes
y = b + 1(wherebis the argument passed bycaller).It prints the value of
y.It restores the old frame pointer and returns to
caller.
Return to Caller:
callerrestores its stack frame.It updates the stack pointer and frame pointer.
It returns to
main.
Return to Main:
maincontinues execution and eventually terminates.
Detailed Low-Level Explanation
Stack Pointer (Sp): Points to the top of the stack. It is adjusted as functions allocate and deallocate space.
Frame Pointer (Fp): Points to the base of the current stack frame. It helps in accessing local variables and arguments.
Return Address: The address in the caller's code to which the callee should return.
Arguments: Values passed from the caller to the callee.
Local Variables: Variables that are local to the function and stored in its stack frame.
When a function is called, the current state (including the return address and frame pointer) is saved, and a new stack frame is created for the callee. When the callee returns, it restores the saved state, and execution continues in the caller.
This mechanism ensures that function calls are managed efficiently, with each function having its own isolated space for variables and control flow.


