Overview
Stack instructions (0x50-0x9f) provide fundamental operations for manipulating the EVM’s 256-bit word stack. These 86 opcodes form the core of EVM computation, enabling value manipulation, duplication, and reordering necessary for all contract execution.Stack Architecture
The EVM stack has strict constraints:- Maximum depth: 1024 items
- Word size: 256 bits (32 bytes) per item
- Access limit: Only top 16 items accessible via DUP/SWAP
- Growth: Downward (item 0 is deepest, item n-1 is top)
- Errors: StackOverflow (>1024), StackUnderflow (<required depth)
Instruction Categories
Stack Removal (0x50)
POP (0x50) - Remove top stack item- Gas: 2
- Stack:
[value] => [] - Use: Discard unneeded values
Push Operations (0x5f-0x7f)
Push immediate values from bytecode onto stack:| Opcode | Name | Bytes | Gas | Since |
|---|---|---|---|---|
| 0x5f | PUSH0 | 0 | 2 | Shanghai (EIP-3855) |
| 0x60 | PUSH1 | 1 | 3 | Frontier |
| 0x61 | PUSH2 | 2 | 3 | Frontier |
| 0x62 | PUSH3 | 3 | 3 | Frontier |
| 0x63 | PUSH4 | 4 | 3 | Frontier |
| 0x64 | PUSH5 | 5 | 3 | Frontier |
| 0x65 | PUSH6 | 6 | 3 | Frontier |
| 0x66 | PUSH7 | 7 | 3 | Frontier |
| 0x67 | PUSH8 | 8 | 3 | Frontier |
| 0x68 | PUSH9 | 9 | 3 | Frontier |
| 0x69 | PUSH10 | 10 | 3 | Frontier |
| 0x6a | PUSH11 | 11 | 3 | Frontier |
| 0x6b | PUSH12 | 12 | 3 | Frontier |
| 0x6c | PUSH13 | 13 | 3 | Frontier |
| 0x6d | PUSH14 | 14 | 3 | Frontier |
| 0x6e | PUSH15 | 15 | 3 | Frontier |
| 0x6f | PUSH16 | 16 | 3 | Frontier |
| 0x70 | PUSH17 | 17 | 3 | Frontier |
| 0x71 | PUSH18 | 18 | 3 | Frontier |
| 0x72 | PUSH19 | 19 | 3 | Frontier |
| 0x73 | PUSH20 | 20 | 3 | Frontier |
| 0x74 | PUSH21 | 21 | 3 | Frontier |
| 0x75 | PUSH22 | 22 | 3 | Frontier |
| 0x76 | PUSH23 | 23 | 3 | Frontier |
| 0x77 | PUSH24 | 24 | 3 | Frontier |
| 0x78 | PUSH25 | 25 | 3 | Frontier |
| 0x79 | PUSH26 | 26 | 3 | Frontier |
| 0x7a | PUSH27 | 27 | 3 | Frontier |
| 0x7b | PUSH28 | 28 | 3 | Frontier |
| 0x7c | PUSH29 | 29 | 3 | Frontier |
| 0x7d | PUSH30 | 30 | 3 | Frontier |
| 0x7e | PUSH31 | 31 | 3 | Frontier |
| 0x7f | PUSH32 | 32 | 3 | Frontier |
- PUSH0: Pushes constant 0 (no bytecode reading)
- PUSH1-32: Read N bytes immediately following opcode
- Big-endian byte order
- Zero-padded to 256 bits
- PC advances by 1 + N bytes
Duplicate Operations (0x80-0x8f)
Duplicate stack items at specific depths:| Opcode | Name | Duplicates | Gas | Stack Effect |
|---|---|---|---|---|
| 0x80 | DUP1 | 1st (top) | 3 | [a] => [a, a] |
| 0x81 | DUP2 | 2nd | 3 | [a, b] => [a, b, b] |
| 0x82 | DUP3 | 3rd | 3 | [a, b, c] => [a, b, c, c] |
| 0x83 | DUP4 | 4th | 3 | [a, b, c, d] => [a, b, c, d, d] |
| 0x84 | DUP5 | 5th | 3 | [a, b, c, d, e] => [a, b, c, d, e, e] |
| 0x85 | DUP6 | 6th | 3 | Stack depth ≥ 6 |
| 0x86 | DUP7 | 7th | 3 | Stack depth ≥ 7 |
| 0x87 | DUP8 | 8th | 3 | Stack depth ≥ 8 |
| 0x88 | DUP9 | 9th | 3 | Stack depth ≥ 9 |
| 0x89 | DUP10 | 10th | 3 | Stack depth ≥ 10 |
| 0x8a | DUP11 | 11th | 3 | Stack depth ≥ 11 |
| 0x8b | DUP12 | 12th | 3 | Stack depth ≥ 12 |
| 0x8c | DUP13 | 13th | 3 | Stack depth ≥ 13 |
| 0x8d | DUP14 | 14th | 3 | Stack depth ≥ 14 |
| 0x8e | DUP15 | 15th | 3 | Stack depth ≥ 15 |
| 0x8f | DUP16 | 16th | 3 | Stack depth ≥ 16 |
- DUP1: Most common, duplicates top
- DUPn: Requires stack depth ≥ n
- Result pushed to top
- Original value unchanged
- StackUnderflow if depth insufficient
Swap Operations (0x90-0x9f)
Exchange top stack item with items at specific depths:| Opcode | Name | Swaps With | Gas | Stack Effect |
|---|---|---|---|---|
| 0x90 | SWAP1 | 2nd | 3 | [a, b] => [b, a] |
| 0x91 | SWAP2 | 3rd | 3 | [a, b, c] => [c, b, a] |
| 0x92 | SWAP3 | 4th | 3 | [a, b, c, d] => [d, b, c, a] |
| 0x93 | SWAP4 | 5th | 3 | [a, b, c, d, e] => [e, b, c, d, a] |
| 0x94 | SWAP5 | 6th | 3 | Stack depth ≥ 6 |
| 0x95 | SWAP6 | 7th | 3 | Stack depth ≥ 7 |
| 0x96 | SWAP7 | 8th | 3 | Stack depth ≥ 8 |
| 0x97 | SWAP8 | 9th | 3 | Stack depth ≥ 9 |
| 0x98 | SWAP9 | 10th | 3 | Stack depth ≥ 10 |
| 0x99 | SWAP10 | 11th | 3 | Stack depth ≥ 11 |
| 0x9a | SWAP11 | 12th | 3 | Stack depth ≥ 12 |
| 0x9b | SWAP12 | 13th | 3 | Stack depth ≥ 13 |
| 0x9c | SWAP13 | 14th | 3 | Stack depth ≥ 14 |
| 0x9d | SWAP14 | 15th | 3 | Stack depth ≥ 15 |
| 0x9e | SWAP15 | 16th | 3 | Stack depth ≥ 16 |
| 0x9f | SWAP16 | 17th | 3 | Stack depth ≥ 17 |
- SWAP1: Most common, exchanges top two
- SWAPn: Requires stack depth ≥ n+1
- Only top and nth item change positions
- Middle items unchanged
- StackUnderflow if depth insufficient
Gas Costs
All stack operations are extremely cheap:| Operation | Gas | Constant |
|---|---|---|
| POP | 2 | GasQuickStep |
| PUSH0 | 2 | GasQuickStep |
| PUSH1-32 | 3 | GasFastestStep |
| DUP1-16 | 3 | GasFastestStep |
| SWAP1-16 | 3 | GasFastestStep |
- Pure stack operations (no memory/storage access)
- No external state reads
- Constant-time execution
- Critical for EVM performance
Common Patterns
Function Selector Matching
Address Literals
Stack Reordering
Efficient Constants
Stack Depth Management
Safe Patterns
Unsafe Patterns
Workarounds
Security Considerations
Stack Underflow
Stack Overflow
PUSH0 Availability
Optimization Techniques
Minimize Stack Operations
Use PUSH0 (Shanghai+)
Reuse Stack Values
Implementation Reference
Stack instruction handlers implemented in:- TypeScript:
/src/evm/stack/handlers/ - Zig:
/src/evm/stack/handlers_stack.zig
- Consume gas
- Validate stack constraints
- Perform operation (pop/push/duplicate/swap)
- Increment program counter
- Return error or null
All Stack Instructions
Complete opcode reference:References
- Yellow Paper - Section 9.1 (Stack)
- EVM Codes - Stack Operations
- EIP-3855 - PUSH0 instruction
- Solidity Stack Layout
- Stack Too Deep Solutions

