Instruction
PUSH
Moves the stack pointer down and stores a register, memory operand, immediate or segment register on top of the stack.
- Extensions
- Forms
- 11 (11 Legacy)
- Data
- Intel XED v2026.08.23
In 64-bit code PUSH appears mostly in function prologues, saving the callee-saved registers a function is about to use; the epilogue restores them with POP in the reverse order. Each push moves RSP by 8, which matters for the ABIs’ rule that RSP is a multiple of 16 at every call: a function entered with RSP 8 past a multiple of 16 is aligned again after an odd number of pushes, and after an even number must move RSP by another 8 before it calls anything (see stack frames). For that slot GCC 14 subtracts 8 from RSP, while Clang 23 may push RAX instead, whose value does not matter.
Operand sizes in 64-bit mode:
- 64 bits by default, without a REX prefix.
- 16 bits with a 66 prefix, which moves RSP by only 2 and leaves it misaligned.
- 32 bits cannot be encoded, as Intel’s and AMD’s manuals both say.
An immediate is sign-extended to 64 bits. push -1 stores eight FFH
bytes, and no PUSH stores 0000000080000000H, because the 32-bit
immediate 80000000H becomes FFFFFFFF80000000H; such a constant goes
through a register.
Two cases involve RSP itself. PUSH RSP stores the value RSP had before
the instruction, as both manuals say and Zen 5 recorded. A memory
operand addressed through RSP, such as push qword [rsp+8], is read
at the address computed before RSP moves, by Intel’s manual; AMD’s
does not say.
PUSH FS and PUSH GS remain in 64-bit mode and store the selector zero-extended to 8 bytes (Zen 5 writes all 8); PUSH of CS, DS, ES and SS is invalid there.
AMD’s optimization guide for Zen 5 says the processor tracks the stack pointer when it renames registers, so a run of PUSH, POP, CALL and RET does not wait for each RSP update. An instruction that uses RSP outside the forms the guide lists, PUSH RSP among them, costs an extra operation and restarts the tracking.
APX adds PUSH2, which pushes two registers at once, and PUSHP, a PUSH with a hint that a matching POPP will follow.
In the optimization guide
What the optimization guide says about PUSH, a line per claim. Each links to the claim in the guide, with its sources and where they differ.
Out of order
- Renaming and the window: A stack engine lets PUSH, POP, CALL and RET change RSP with no execution unit and no wait, though an explicit use of RSP between them can cost an extra micro-op.
Jaguar and Puma
- Front end: A sideband stack optimizer in the decoder tracks the stack pointer, so a chain of PUSH and POP instructions does not wait on each update of rSP.
Silvermont to Goldmont Plus
- Front end: On Silvermont these instructions come from the microcode ROM; Goldmont decodes them directly, except an indirect call through memory.
- Out-of-order and in-order execution: Goldmont tracks the stack pointer of
push,pop,callandretwithout spending allocation or execution slots on it, and runspushandpopthree a cycle where Silvermont runs one. - Out-of-order and in-order execution: LLVM’s tuning for all four cores loads the operand of
pushandcallinto a register first, and prefersmovbeto a load and abswap.
Tremont
- Integer execution: LLVM’s tuning treats
push,popandcallwith a memory operand as slow on this core and loads the operand into a register first.
Zen and Zen+
- Integer execution: The decoder tracks RSP, so chains of PUSH and POP do not wait for each other; Agner Fog found PUSH, POP and RET to be one macro-op each, with no latency on RSP.
Zen 2
- Integer execution: A stack engine tracks RSP, so chains of PUSH and POP do not wait for each other; Agner Fog found PUSH, POP and RET to be one macro-op each with no latency on RSP.
Zen 3
- Integer execution: PUSH, POP, CALL and RET update RSP without a dependency, and loads, stores,
leaandmovfrom RSP can use the tracked value.
Zen 4
- Integer execution: PUSH, POP, CALL and RET update RSP without a dependency, and loads, stores,
leaandmovfrom RSP can use the tracked value.
Zen 5
- Integer execution: PUSH, POP, CALL and RET update RSP without a dependency, and loads, stores,
leaandaddorsubof a small immediate through RSP can use the tracked value.
Forms
| Instruction | Encoding | Requires |
|---|---|---|
PUSH m16/32/64
PUSH_MEMv | FF /6 | Base instruction set |
PUSH r16/32/64
PUSH_GPRv_FFr6 | FF /6 | Base instruction set |
PUSH ES not in 64-bit mode
PUSH_ES | 06 | Base instruction set |
PUSH CS not in 64-bit mode
PUSH_CS | 0E | Base instruction set |
PUSH SS not in 64-bit mode
PUSH_SS | 16 | Base instruction set |
PUSH DS not in 64-bit mode
PUSH_DS | 1E | Base instruction set |
PUSH r16/32/64
PUSH_GPRv_50 | 50+rREX2.W0 50+r | Base instruction set |
PUSH imm16/32
PUSH_IMMz | 68 iw/id | Base instruction set |
PUSH imm8
PUSH_IMMb | 6A ib | Base instruction set |
PUSH FS
PUSH_FS | 0F A0 | Base instruction set |
PUSH GS
PUSH_GS | 0F A8 | Base instruction set |
Latency and throughput
| Model | m16 | m64 | r16imm8 | r64 | imm32 |
|---|---|---|---|---|---|
| Sandy Bridge | 5 / 1p4 p23 | 5 / 1p4 p23 | 5 / 1p4 p23 | 5 / 1p4 p23 | 1 / 1p4 p23 |
| Haswell | 7 / 1p0156 | 7 / 1p0156 | 2 / 1p01234567 | 2 / 1p01234567 | 1 / 1p2347 |
| Broadwell, Skylake, Skylake-SP | 6 / 1p0156 | 6 / 1p0156 | 2 / 1p01234567 | 2 / 1p01234567 | 1 / 1p2347 |
| Ice Lake | 6 / 0.5p0156 | 6 / 0.5p0156 | 2 / 0.5p01456789 | 2 / 0.5p01456789 | 1 / 0.5p4789 |
| Alder Lake, Sapphire Rapids | 12 / 0.5p2 p3 p4 p7 p8 p9 p10 | 1 / 0.5p2 p3 p4 p7 p8 p9 p10 | 12 / 0.5p4789 | 1 / 0.5p4789 | 12 / 0.5p4789 |
| Lunar Lake | 12 / 0.5p10 p11 p20 p21 p22 p25 p26 p27 | 1 / 0.5p10 p11 p20 p21 p22 p25 p26 p27 | 12 / 0.5p10 p11 p25 p26 p27 | 1 / 0.5p10 p11 p25 p26 p27 | 12 / 0.5p10 p11 p25 p26 p27 |
| Bonnell | 2 / 1p1 | 2 / 1p1 | 1 / 1p01 | 1 / 1p01 | 1 / 1p01 |
| Silvermont | 4 / 2IEC0 IEC1 MEC | 4 / 2IEC0 IEC1 MEC | 1 / 1IEC0 IEC1 MEC | 1 / 1IEC0 IEC1 MEC | 1 / 1IEC0 IEC1 MEC |
| Piledriver | 6 / 1.5AGLU01 Load Store | 6 / 1.5AGLU01 Load Store | 1 / 1AGLU01 Store | 1 / 1AGLU01 Store | 1 / 1AGLU01 Store |
| Zen | 4 / 0.5AGU0 AGU1 | 5 / 1AGU0 AGU1 | 1 / 0.5AGU0 AGU1 | 1 / 0.5AGU0 AGU1 | 1 / 0.5AGU0 AGU1 |
| Zen 2 | 4 / 0.33AGU0 AGU1 AGU2 | 5 / 0.67AGU0 AGU1 AGU2 | 1 / 0.33AGU0 AGU1 AGU2 | 1 / 0.33AGU0 AGU1 AGU2 | 1 / 0.33AGU0 AGU1 AGU2 |
| Zen 3, Zen 4 | 6 / 1AGU0 AGU1 AGU2 LSU Load Store | 6 / 1AGU0 AGU1 AGU2 LSU Load Store | 1 / 1AGU0 AGU1 AGU2 LSU Store | 1 / 1AGU0 AGU1 AGU2 LSU Store | 1 / 1AGU0 AGU1 AGU2 LSU Store |
| Jaguar | 4 / 1LAGU SAGU | 4 / 1LAGU SAGU | 1 / 1SAGU | 1 / 1SAGU | 1 / 1SAGU |
Operation
What the forms do, in pseudocode that our tests run against results recorded on real processors. How to read.
PUSH imm16/32 PUSH imm8 PUSH r/m16/32/64v = sext(src) # an immediate is sign-extended to OSIZE
a = rsp - OSIZE // 8 # 8 bytes, or 2 with a 66 prefix
store(a, OSIZE, v) # PUSH RSP pushes RSP from before
rsp = aRun on AMD Zen 5 (EPYC 9645): 60 cases.
PUSH ES not in 64-bit mode PUSH CS not in 64-bit mode PUSH SS not in 64-bit mode PUSH DS not in 64-bit mode PUSH FS PUSH GSa = rsp - OSIZE // 8
store(a, OSIZE, src) # the selector, zero-extended
rsp = aRun on AMD Zen 5 (EPYC 9645): 8 cases. The forms that 64-bit mode lacks were not run: the probe runs in 64-bit mode.
Operands
| Operand | Kind | Action |
|---|---|---|
PUSH r/m16/32/64 | ||
r/m16/32/64 | explicit | read |
stack | implicit | write |
rSP | implicit | read, write |
PUSH ES not in 64-bit mode PUSH CS not in 64-bit mode PUSH SS not in 64-bit mode PUSH DS not in 64-bit mode PUSH FS PUSH GS | ||
ES, CS, SS, DS, FS, GS | explicit | read |
stack | implicit | write |
rSP | implicit | read, write |
PUSH imm16/32 PUSH imm8 | ||
imm8/16/32 | explicit | read |
stack | implicit | write |
rSP | implicit | read, write |
Flags
None: XED records no flag that the forms test or change.
CPUID and processors
Each form belongs to an XED ISA set. A form can be used when the processor reports every CPUID bit of one of its ISA set's alternatives.
| ISA set | CPUID | Processors |
|---|---|---|
I86 | No CPUID bit: part of the base instruction set. | Every x86-64 processor in XED’s model and Zen 3 to Zen 6 |
I186 | No CPUID bit: part of the base instruction set. | Every x86-64 processor in XED’s model and Zen 3 to Zen 6 |
More General-purpose instructions
Sources
- Intel XED v2026.08.23 (commit
0bcb6237345c): forms, encodings, operands, flags, exception classes, attributes, ISA sets, CPUID bits and chip model. - The CPU data of x86-64.net: Zen 3 to Zen 6, from GCC’s
-marchfeature sets and AMD’s Processor Programming References, which the page of each processor cites. - LLVM 23.1.2's x86 scheduling models (commit
85ac56026243): the latency, reciprocal throughput and ports of each form, as llvm-mca reports them. - Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 2 (325383-093, September 2026): Volume 2B, page 4-522 (PUSH)
- AMD64 Architecture Programmer's Manual, Volume 3: General-Purpose and System Instructions (24594, rev. 3.39, October 2026)
- Software Optimization Guide for the AMD Zen5 Microarchitecture (58455, rev. 1.00, August 2024), Wayback Machine copy of AMD's ZIP
The tables are derived from Intel XED, Copyright Intel Corporation, licensed under the Apache License 2.0; x86-64.net converted and reformatted them. The timings come from LLVM's scheduling models, part of the LLVM Project, licensed under the Apache License 2.0 with LLVM Exceptions. The text is our own.