2026-07-22
You write mov rax, rbx in assembly. Reading a value from one register and writing it to another sounds like the simplest possible instruction: one ALU pass-through, one cycle, done. Modern x86 and ARM cores do better than that — they execute it in zero cycles, without any functional unit touching a wire. The trick lives entirely in the rename stage.
Recall from register renaming that architectural registers (RAX, RBX...) are just names, and the physical register file (PRF) has hundreds of real storage slots. The rename table (RAT) maps architectural names to physical tags. When you write RAX, the renamer allocates a fresh physical register (say P37) and updates RAT[RAX] = P37.
The move-elimination insight: mov rax, rbx doesn't need new storage — it just needs RAX to point at whatever RBX currently points at. So the renamer executes it by copying the map entry:
The instruction retires the moment it's decoded. It uses zero ALU bandwidth, zero PRF write ports, and its latency for any dependent instruction is –1 cycle relative to normal: dependents can read P22 the same cycle the move is renamed.
Concrete example: Intel introduced this in Ivy Bridge (2012); AMD added it in Bulldozer. Agner Fog's tables confirm on Skylake/Zen, GP-register mov r64, r64 is eliminated ~100% of the time. In real code, compilers emit surprising numbers of moves — function ABI shuffling (moving arg registers to callee-saved), SSA-to-machine lowering, and idioms like lea-as-move. A recompile of SPEC benchmarks shows 3-6% of dynamic instructions are eliminated moves.
Rule of thumb: if two architectural registers hold identical values from a MOV, they alias to one physical register until either is overwritten. The PRF's reference-count bit tracks this; free-list return happens only when refcount hits zero.
Where it breaks: partial-register writes (mov ax, bx), sign/zero-extending moves, and cross-domain moves (GPR↔XMM) generally can't be eliminated — they need actual data manipulation. Also, XOR-zero idioms (xor eax, eax) are handled separately: they don't alias, they allocate a physical zero register.
