Process
Each process is running on its own virtual address space. The MMU does the necessary translation from/to the physical address space. Every thread within a process has its own stack.
Address space
High address |-------------------| 0xFFFFFFFFFFFFFFFF* | | | Kernel space | | | 0xFFFF800000000000* |-------------------| | | 0x00007FFFFFFFFFFF* | User space | | | Low address |-------------------| 0x0000000000000000* Process * AMD64/x86-64 (Invalid: 0x0000800000000000 - 0xFFFF7FFFFFFFFFFF)
User space
High address |-------------------| 0x00007FFFFFFFFFFF* | Command Line Args | |-------------------| | Stack (Thread 0) | |-------------------| | ↓ | |-------------------| | Stack (Thread N) | |-------------------| | ↓ | | | /|------| |-------------------|/ | Data | | Shared library 0 | |------| |-------------------|\ | Code | | ... | \|------| |-------------------| | Shared library N | |-------------------| | | | ↑ | |-------------------| | Heap | |-------------------| | Data | |-------------------| | Code | Low address |-------------------| 0x0000000000000000* Process * AMD64
Stack
With every function call a new stack frame gets created for the callee on the stack and as soon as it returns to the caller function that stack frame has been destructed.
(High address) /|----------------------| / | Caller-saved Reg [1] | / |----------------------| / | Argument 1 | High address |---------------| / |----------------------| | Stack Frame 0 | / | Argument 0 | |---------------| / |----------------------| | Stack Frame 1 | / | Caller Ret Addr | (Old RIP) |---------------|/ |----------------------| | Stack Frame 2 | | Caller Base Ptr | (Old RBP) Low address |---------------|\ |----------------------| <-- Base Pointer Stack \ | Callee-saved Reg [2] | (RBP) ↓ \ |----------------------| Grow direction \ | Local Var 0 | \ |----------------------| \ | Local Var 1 | \ |----------------------| \ | Temp Objects | (Low address) \|----------------------| <-- Stack Pointer [3] Stack Frame 2 (RSP)
[1] Cached by the caller if it wants the old state later on.
[2] Cached by the callee if it wants to use them by their own.
[3] Points to the top of the stack of the selected thread.
Disclaimer
- The used register names are from the x86-64 Architecture.
- In a gdb backtrace the frames are in the opposite order.
Heap
The data on the heap isn't as moderated and strictly structured as the one on the stack. You even have to clean up by yourself, if you haven't got a garbage collector.