Article by Ayman Alheraki on January 11 2026 10:35 AM
In Assembly language, managing memory efficiently is crucial, particularly through the use of the Stack and Heap, each serving different purposes with specific usage techniques.
The Stack is a memory region used to store temporary data needed by functions and subroutines during execution. It is primarily used for:
Passing parameters to functions.
Storing return addresses (i.e., where the function should return after completion).
Holding local variables that are only required temporarily within a function.
Operates on a LIFO (Last In, First Out) basis, meaning data is added and removed in a specific order.
Stack size is fixed during runtime and is limited in growth, depending on recursive calls or function nesting.
In this example, we use the Stack to store some values temporarily during function execution:
section .data ; Define data if needed
section .text global _start
_start: ; Simple example of adding two numbers
; Push values onto the Stack push dword 5 ; Push 5 to the Stack push dword 10 ; Push 10 to the Stack
; Pop values from the Stack and add them pop eax ; Pop first value into eax pop ebx ; Pop second value into ebx add eax, ebx ; Add values, result stored in eax
; Exit program mov eax, 1 int 0x80 ; Linux system call to terminate programParameter Passing: For passing values to subroutines.
Return Address Management: Storing the return address for subroutine calls.
Temporary Local Variables: For temporary variables needed only during the function's execution.
The Heap is a memory region designed for storing long-lived or dynamically-sized data. Unlike the Stack, Heap memory allocation is managed manually.
The Heap is virtually unlimited, expanding as needed based on available system memory.
Memory in the Heap is manually managed, requiring explicit allocation and deallocation by the programmer.
Data stored in the Heap persists beyond the function’s scope, making it ideal for long-term data storage.
Using Linux, we can use the mmap syscall to allocate memory on the Heap.
section .data ; No static data defined
section .text global _start
_start: ; Setting up parameters for mmap syscall mov eax, 0x5D ; mmap syscall number xor ebx, ebx ; Suggested address (0 means auto-selected) mov ecx, 100 ; Memory size requested (100 bytes) mov edx, 3 ; PROT_READ | PROT_WRITE - read/write permission mov esi, 0x22 ; MAP_PRIVATE | MAP_ANONYMOUS flags xor edi, edi ; File descriptor (0, as we’re not using one) xor ebp, ebp ; Offset (not needed)
int 0x80 ; Call mmap syscall
; After mmap, eax contains the base address of allocated memory mov ebx, eax ; Store allocated address in ebx for later use
; Performing operations with allocated memory mov dword [ebx], 0x12345678 ; Write a value into the allocated memory
; Freeing the memory with munmap syscall after usage mov eax, 0x5B ; munmap syscall number int 0x80 ; Call munmap to free memory
; Exit program mov eax, 1 int 0x80 ; Linux system call to terminate programDynamic Storage: When data size and lifespan are not predetermined.
Cross-Function Data Persistence: Data needs to persist beyond the subroutine’s lifecycle.
Large Objects: For storing larger data structures that would overwhelm the Stack.
| Stack | Heap | |
|---|---|---|
| Management | Automatic (aligned with function calls) | Manual (explicit allocation/deallocation) |
| Performance | Faster | Slower |
| Capacity | Limited | Virtually unlimited |
| Data Usage | Temporary/local variables | Long-term, dynamic data |
| Access | LIFO (Push/Pop) | Accessed via allocated pointers |
Understanding both the Stack and the Heap is essential for memory management in Assembly programming. This knowledge is invaluable for creating efficient applications, allowing developers to control resources precisely.