Subprogram Sequence Control
System Programming | Compiler Design | Exam Notes
1. Subprogram Sequence Control — Overview
Subprogram sequence control is the mechanism that manages the transfer of control between a
calling program and a called subprogram, ensuring proper execution order using call, return,
and stack-based activation records.
In simple terms, it decides:
• How a function call happens
• How control is transferred to the subprogram
• How control returns to the caller
Real Life Analogy
Main Program = Boss (You) Subprogram = Worker
"Go do this work" → Function Call Worker does the task → Execution
"Bring back the result" → Return Worker returns → Control back to boss
2. Important Components
Return Address
When a function is called, the system stores a return address — which tells the program where
to continue execution after the function completes.
main() {
fun(); // execution returns here after fun() finishes
}
Activation Record (Stack Frame)
Each function call creates an activation record on the stack containing:
• Local variables
• Parameters
• Return address
Call Stack
The call stack uses a LIFO (Last In, First Out) structure to manage function calls. Example call
chain: main() → fun1() → fun2(). Return order: fun2 → fun1 → main.
3. Stack Behavior in Calls
When a function is called, a new stack frame is pushed. When it returns, that frame is popped.
This LIFO mechanism ensures execution resumes at the correct point.
Push Function call → new stack frame pushed to the top of the call stack
Execute Function runs its body; stack grows if nested calls occur
Pop Return statement → stack frame popped; control returns to caller
4. Types of Subprogram Sequence Control
Simple Call-Return
Standard function call — one call leads to one return. Control flows linearly from caller to callee
and back.
Recursive Calls
A function calls itself. Each recursive call gets its own stack frame. A base case is essential to
terminate recursion.
int fact(int n) {
if (n == 0) return 1; // base case
return n * fact(n-1); // recursive call
}
Warning: Deep recursion can cause Stack Overflow — the stack runs out of memory.
Nested Subprogram Calls
One function calls another, which may call another. The call stack grows with each level and
unwinds on each return.
Coroutines (Advanced)
Control switches between two routines without a full return — execution is paused and
resumed. Used in cooperative multitasking and async programming.
5. Parameter Passing Methods
Different strategies exist for passing data into functions:
• Call by Value — copy of the variable is passed
• Call by Reference — original variable's address is passed
• Call by Address — explicit pointer is passed
• Call by Value-Result — copy in, copy back on return (advanced)
6. Call by Value
A copy of the actual parameter is passed to the function. Changes inside the function do NOT
affect the original variable.
void fun(int x) {
x = x + 10; // only the copy changes
}
int main() {
int a = 5;
fun(a);
// a is still 5 here
}
• Safe — original data is protected
• No side effects on the caller's variables
• Extra memory needed for the copy
7. Call by Reference
The memory address (reference) of the actual variable is passed. The function works directly on
the original variable, so changes ARE reflected in the caller.
void fun(int &x) {
x = x + 10; // original variable is modified
}
int main() {
int a = 5;
fun(a);
// a is now 15 here
}
• Faster — no copy overhead
• Original variable is directly modified
• Risk of unintended side effects
8. Call by Value vs Call by Reference — Comparison
Feature Call by Value Call by Reference
Data Pass Copy of variable Original variable (address)
Memory Extra memory used (copy) No extra copy
Effect on Original No change Original is changed
Speed Slower (copy overhead) Faster (no copy)
Safety High (data protected) Low (can modify data)
Memory Tip Value = Copy → No Change | Reference = Real → Change
9. Control Flow Between Subprograms
The control flow in subprogram calls follows a predictable path:
1. Main program encounters a function call
2. Control is transferred to the function's entry point
3. Function executes its body
4. Return value (if any) is passed back to the caller
5. Stack frame is popped; execution resumes in main program
For nested calls: main → f1 → f2 → f3, the return is in reverse: f3 → f2 → f1 → main.
10. Advantages of Subprograms
• Code Reuse — write once, call many times
• Modularity — break complex code into smaller, manageable parts
• Easier Debugging — isolate and test individual functions
• Maintainability — update one function without changing others
• Improved Readability — self-documenting function names clarify intent
11. Disadvantages of Subprograms
• Stack Overflow — deep or infinite recursion exhausts stack memory
• Extra Memory Usage — each call creates a new stack frame
• Execution Overhead — call and return instructions consume CPU cycles
• Complex Debugging — tracing deeply nested or recursive calls can be difficult
12. Real-Life Applications
Recursion Use Cases
• Factorial and Fibonacci calculations
• Tree and graph traversal (DFS, BFS)
• Divide and conquer algorithms (merge sort, quick sort)
System Software
• Compilers — handling and optimizing function calls
• Operating Systems — process call stack management
Web Development
• API request handling and routing
• Backend business logic organized as callable services
Data Structures
• Recursive operations on stacks, trees, and graphs
Quick Revision — Exam Summary
Stack Manages function calls using LIFO
Activation Record Stores local vars, params, return address per call
Recursion Function calling itself; needs base case
Call by Value Copy passed — original not changed
Call by Reference Address passed — original is changed
Control Flow Call → Execute → Return (stack-managed)
Advantages Modular, reusable, readable
Disadvantages Stack overflow, memory, overhead