Assembly
Push and Pop Instructions
Push and pop behaviour
- When
push:espdecreases (stack grows down, toward lower addresses) - When
pop:espincreases (back toward higher addresses) - 32-bit (x86): each push/pop moves
espby 4 bytes - 64-bit (x86-64): each push/pop moves
rspby 8 bytes
nasm
push eax
# Equivalent to:
sub esp, 4
mov [esp], eaxespdrops by 4 (moves to a lower address)- The value in
eaxis copied to memory at the newesplocation eaxstays unchanged
nasm
pop ebx
# Equivalent to:
mov ebx, [esp]
add esp, 4- Value at
[esp]is copied intoebx espgoes up by 4 (moves to a higher address)
Stack layout example
nasm
push 18 ; First push
push 24 ; Second push
push 48 ; Third push
push 64 ; Fourth push (most recent)Memory layout (lowest address on the left, so esp points at the most recent push):
text
Lower addr Higher addr
0xFFD0 0xFFD4 0xFFD8 0xFFDC
[ 64 ] [ 48 ] [ 24 ] [ 18 ]
^ esp esp+4 esp+8 esp+12
mov eax, [esp] ; eax = 64 (top of stack)
mov eax, [esp+4] ; eax = 48Removing multiple items
nasm
# Instead of multiple pops...
pop eax
pop eax
pop eax
pop eax
# ...just move esp directly
add esp, 16 ; Remove 4 dwords (4 x 4 bytes)pop just moves esp up and copies data, so it can skip the copy and only adjust esp. Useful for
discarding unwanted stack data. The values stay in memory until overwritten, but never read below
esp — that's the "unused" part of the stack.
pusha/popa extension
- pusha (push all words): pushes all 16-bit general purpose registers — AX, BX, CX, DX, SI, DI, SP, BP
- pushad (push all double words): pushes all 32-bit general purpose registers — EAX, EBX, ECX, EDX, ESI, EDI, ESP, EBP
- popa: pops in order DI, SI, BP, BX, DX, CX, AX; SP is adjusted to reflect the new top of stack
- popad: pops in order EDI, ESI, EBP, EBX, EDX, ECX, EAX; ESP is adjusted to reflect the new top of stack
Note: pusha/popad only exist in 16/32-bit mode — no 64-bit version.
Save and restore registers
nasm
push eax ; Save original value
; ... do work that modifies eax ...
pop eax ; Restore original valueStack overflow happens when pushing too much and running out of stack space. The OS sets up the
initial stack with environment variables and program arguments before _start.