ScholarQuill logoScholarQuillUniversity Notes
My Semester
Explore Notes
Past Papers12 New
Video CoursesNew
Search
Settings
Study Tools
GPA/CGPA Calculator
Schedule & To-Do
Student Portal
Contact
Contact
ScholarQuill logo
My Semester
Explore Notes
Past Papers12 New
Video CoursesNew
Search
Settings
GPA/CGPA Calculator
Schedule & To-Do
Student Portal
Contact
ScholarQuill logoScholarQuillUniversity Notes
Study PortalCOMP3137Runtime Stack
Ctrl + K
Login
Explore
Search
Semester
Papers
CGPA
    COMP3137

    Computer Organization and Assembly Language

    Progress0 / 73 done
    Topics73
    1Introduction to Computer Organization2Assembly Language3Comparison of Low-Level and High-Level Languages
    4General Purpose and Special Purpose Registers5Introduction and Usage of RAM6Processor7Registers8System Bus9Instruction Execution Cycle10Assembly and Machine Language11Assembler12Linker and Link Libraries13Programmer's View of a Computer System14RISC and CISC Architecture15Physical Address Calculation16Basic Memory Organization17CPU Organization18Top Level View of Computer Function and Interconnection19Assembler Instruction Cycle20Execute Cycle21Interrupts22Interrupt Cycle23Memory Connection24Input/Output Connection25CPU Connection26MASM27MIPS28Defining Data in MASM Assembler29Elements of Assembly Language30Integer Constants31Integer Expressions32Real Number Constants33Character Constants34String Constants35Reserved Words36Identifiers37Directives38Instructions39The NOP (No Operation) Instruction40Adding and Subtracting Integer41INC and DEC Instructions42NEG Instruction43How to Move Integer Number in Register44Adding and Subtracting Numbers in Registers45Declaration and Initialization of Variables46Moving Data from Variable to Register47Data Definition Statement48BYTE and SBYTE Data49WORD and SWORD Data50Defining DWORD and SDWORD Data51Knowledge about Different Data Types52Operations, Array & Loops53Division and Multiplication in Assembly54Jumps Based on Specific Flags55Jumps Based on Equality56Simple Jump Statements57Jumps Based on Specific Condition58Code Examples59Practice on MASM60Procedures61File Operations Procedures62Labels in Procedures63Stack64Runtime Stack65Conditional Control Flow Directives66Compound Expressions67Data Representation & Conversion68Architecture69Data Path70Control Unit71Critical Path72General Principles of Pipelining73Pipelined Y86 Implementations
    8 min read
    Topic 64 of 73
    Topic Study Note Illustration
    64

    Runtime Stack

    The runtime stack , often simply called the stack , is a critical part of a computer’s memory management system used by the CPU during the execution...

    Runtime Stack

    The runtime stack, often simply called the stack, is a critical part of a computer’s memory management system used by the CPU during the execution of programs. It stores information such as local variables, function parameters, return addresses, and information about the function calls themselves. The runtime stack is used during function calls and returns, and it helps manage the flow of execution in a program.

    Let’s break down the concepts and importance of the runtime stack, and how it functions in the context of program execution.


    Structure of the Runtime Stack

    The runtime stack is organized as a last-in, first-out (LIFO) data structure. This means that the last item pushed onto the stack is the first one to be popped off. This organization is particularly suited for managing function calls and returns.

    The runtime stack typically consists of the following components:

    1. Function Call Frame (Stack Frame)
    2. Return Address
    3. Local Variables
    4. Function Arguments/Parameters
    5. Saved Registers
    6. Stack Pointer (SP)

    Components of the Runtime Stack

    1. Function Call Frame (Stack Frame)

    Each time a function is called, a new stack frame is created on the stack. This stack frame contains all the data needed to manage the function’s execution, such as the function's parameters, local variables, and the return address.

    A stack frame typically contains:

    • Return Address: The address to return to once the function finishes executing. This is stored in the stack frame by the call instruction when a function is called.
    • Function Arguments: The values passed to the function when it is called. These are typically pushed onto the stack by the calling function.
    • Local Variables: The variables that are declared within the function. Each function gets its own space for local variables in the stack frame.
    • Saved Registers: Some registers are saved to the stack so that their values can be restored after a function call (to preserve state).

    2. Return Address

    When a function is called, the address to which the program should return after the function finishes is stored on the stack. This is important for ensuring that control can return to the correct place in the program once the function has completed its execution.

    3. Local Variables

    Local variables are those declared within the function. These are stored in the stack frame of the function and are removed when the function returns. Since the stack is LIFO, each function gets a fresh space on the stack for its local variables, and these variables are discarded when the function exits.

    4. Function Arguments/Parameters

    The arguments (or parameters) passed to a function are also stored on the stack, either before or after the function’s stack frame. In many calling conventions, the arguments are pushed onto the stack in reverse order (right to left).

    5. Saved Registers

    Before calling a function, the calling function may save the values of certain registers (such as the base pointer, or BP) to the stack to ensure that they can be restored when the function finishes executing. This is part of the function prologue (the set of instructions executed when a function is entered).


    How the Runtime Stack Works

    The operation of the runtime stack is best understood by looking at the sequence of events during function calls and returns:

    1. Function Call

    • When a function is called, the return address (the point to continue execution after the function completes) is pushed onto the stack.
    • The arguments to the function are pushed onto the stack, either by the calling function or directly as part of the function call.
    • A new stack frame is created for the called function. This contains the space for local variables, saved registers, and other necessary data.
    • The program control then jumps to the called function, which begins execution.

    2. Function Execution

    • Inside the function, local variables are allocated space within the function’s stack frame.
    • The function executes its instructions and manipulates local variables and registers.
    • If the function makes any other function calls, similar steps occur: a new stack frame is pushed for the called function, and the return address and arguments are stored.

    3. Function Return

    • When the function completes its execution, it needs to return control to the calling function.
    • The return value (if any) is often placed in a specific register (such as EAX in x86), and the stack frame for the function is cleaned up.
    • The return address (stored in the stack frame) is popped from the stack, and the program counter (PC) is updated to this address.
    • The saved registers are restored, and the stack pointer is adjusted to remove the current stack frame.
    • Control returns to the calling function, and the calling function continues execution from the point after the function call.

    Example of Stack Usage: Function Call and Return

    Let’s consider a simple example of function calls using the runtime stack in a pseudo-assembly language.

    1. Main Program (Calling function):

      push 5           ; Push argument for funcA
      call funcA       ; Call function funcA
      ; Execution continues here after funcA returns
      
    2. Function A:

      funcA:
      push ebp         ; Save the base pointer (if necessary)
      mov ebp, esp     ; Set up stack frame (save current stack pointer)
      push dword [ebp+8] ; Push argument passed to funcA (parameter 5)
      ; Function A does something with the argument...
      pop ebp          ; Restore the base pointer
      ret              ; Return control to the calling function
      

    Flow of execution:

    • Main Program pushes the argument 5 onto the stack and then calls funcA.
    • The call funcA instruction pushes the return address (the location where execution should continue after the function returns) onto the stack.
    • funcA pushes the base pointer (ebp) onto the stack to save the current frame, then sets up its own stack frame.
    • funcA accesses the argument (stored at [ebp+8]) and performs its task.
    • Upon completing execution, funcA pops the stack pointer (restoring the base pointer) and returns control to the Main Program by using the ret instruction, which pops the return address from the stack and jumps back to the calling code.

    Stack Overflow and Stack Underflow

    • Stack Overflow: Occurs when the program uses more space on the stack than is available, often due to excessive function calls (e.g., infinite recursion). This leads to overwriting data and crashes the program.

    • Stack Underflow: Happens when a function attempts to return or pop data from the stack that hasn’t been pushed onto the stack. This can occur when the stack pointer is incorrectly manipulated or when a function tries to pop more data than was pushed.

    Both stack overflow and stack underflow can cause serious program errors and crashes.


    Stack in Recursion

    The stack is crucial for managing recursion, where a function calls itself. Each recursive call pushes a new stack frame, allowing the program to maintain separate local variables and return addresses for each recursive call. The stack unwinds when the base case is reached, and control is returned from each recursive function in reverse order.

    For example, consider a simple recursive function to compute the factorial of a number:

    int factorial(int n) {
        if (n == 0) return 1;
        return n * factorial(n - 1);
    }
    

    Each call to factorial() pushes a new frame onto the stack. When factorial(5) is called, the stack will look like this:

    • factorial(5) — frame 1
    • factorial(4) — frame 2
    • factorial(3) — frame 3
    • factorial(2) — frame 4
    • factorial(1) — frame 5
    • factorial(0) — base case

    Once the base case is reached, the stack begins to unwind, returning control to each previous call and ultimately computing the result.


    Conclusion

    The runtime stack is a fundamental part of program execution, managing function calls and returns, local variables, and function arguments. It allows for proper function nesting, recursion, and state preservation across function calls. By understanding how the stack works, you gain insights into the inner workings of program execution and the flow of data within a computer's memory.

    ← Previous topic 63
    Stack
    Next topic 65 →
    Conditional Control Flow Directives

    Past Papers

    Open this section to view and download past papers

    Click on Show Past Papers to load available exam papers.

    Reading Progress
    0%
    8mremaining
    1.3kwords
    Intermediatelevel
    On This Page

    No headings found

    Study Toolkit

    Subject Portal

    Computer Organization and Assembly Language