3.2.2. Stack

The process stack is typically used for return addresses, procedure arguments, temporarily saved registers and locally allocated variables. The processor typically contains a register that points to the top of the stack. This register is called the stack pointer and is implicitly used by machine code instructions that call a procedure, return from a procedure, store a data item on the stack and fetch a data item from the stack.

The use of stack for procedure arguments and locally allocated variables relies on the fact that the arguments and the variables reside in a constant position relative to the top of the stack. The processor typically allows addressing data relative to the top of the stack, making it possible to use the same machine code instructions to access the procedure arguments and the locally allocated variables regardless on their absolute addresses in the virtual address space, as long as their addresses relative to the top of the stack do not change.

Allocating the block that contains stack requires estimating the stack size. Typically, the block is allocated with a reasonable default size and an extra page protected against reading and writing is added below the end of the allocated block. Should the stack overflow, an attempt to access the protected page will be made, causing an exception. The operating system can handle the exception by growing the block that contains stack and retrying the machine code instruction that caused the exception.

A multithreaded program requires as many stacks as there are threads. This makes placing the block that contains stack more difficult with respect to growing the block later, unless segmentation or split stack is used.

3.2.2.1. Example: Stack On Intel 80x86 Processors

The Intel 80x86 processors have a stack pointer register called ESP . The CALL machine code instruction decrements the ESP register by the size of a return address and stores the address of the immediately following machine code instruction to the address pointed to by the ESP register. Symetrically, the RET machine code instruction fetches the stored return address from the address pointed to by the ESP register and increments the ESP register by the size of a return address. The PUSH and POP machine code instructions can be used to store and fetch an arbitrary register to and from the stack in a similar manner.

Note that the stack grows towards numerically smaller addresses. This simplifies the process memory management when only one stack block is present, as it can be placed at the very end of the virtual address space rather than in the middle of the virtual address space, where it can collide with other blocks that change during process execution.

To address the stack content, the Intel 80x86 processors have a base pointer register called EBP . The EBP register is typically set to the value of the ESP register at the beginning of a procedure, and used to address the procedure arguments and locally allocated variables throughout the procedure. Thus, the arguments are located at positive offsets from the EBP register, while the variables are located at negative offsets from the EBP register.

void SomeProcedure (int anArgument)
{
  int aVariable;
  aVariable = anArgument;
}

SomeProcedure:

    push    ebp             ;save original value of EBP on stack
    mov     ebp,esp         ;store top of stack address in EBP
    sub     esp,4           ;allocate space for aVariable on stack

    mov     eax,[ebp+8]     ;fetch anArgument into EAX, which is
                            ;8 bytes below the stored top of stack
    mov     [ebp-4],eax     ;store EAX into aVariable, which is
                            ;4 bytes above the stored top of stack

    mov     esp,ebp         ;free space allocated for aVariable
    pop     ebp             ;restore original value of EBP
    ret                     ;return to the caller

In the example, the stack at the entry to SomeProcedure contains the return address on top, that is 0 bytes above the value of ESP , and the value of anArgument one item below the top, that is 4 bytes above the value of ESP . Saving the original value of EBP stores another 4 bytes to the top of the stack and therefore decrements the value of ESP by another 4 bytes, this value is then stored in EBP . During the execution of SomeProcedure, the value of anArgument is therefore 8 bytes above the value of EBP . Note that the machine code instructions used to access the procedure arguments and the locally allocated variables do not use absolute addresses in the virtual address space of the process.