Skip to content

x86-64 vs ARM64 Instruction Map: Side-by-Side Assembly Reference

This x86-64 vs ARM64 instruction map shows the most common assembly instructions on both dominant 64-bit architectures side by side. Use it as a translation table when reading disassembly, porting code, or studying compiler output across platforms.

This x86-64 vs ARM64 instruction map shows the most common assembly instructions on both dominant 64-bit architectures side by side. Use it as a translation table when reading disassembly, porting code, or studying compiler output across platforms. Each row shows the equivalent operation with key architectural differences noted.

For hands-on tutorials, see my Assembly Syscall Deep Dive (Linux/macOS, both architectures) and Calling Conventions Demystified.


1. Data Movement

The biggest difference in data movement is that ARM64 is a load-store architecture — arithmetic instructions cannot access memory directly. x86-64 allows memory operands in most instructions, enabling direct manipulation of data at memory addresses.

Operationx86-64ARM64Notes
Register → Registermov rax, rbxmov x0, x1
Immediate → Registermov rax, 42mov x0, #42ARM64: 16-bit per movz/movk
Load from memorymov rax, [rbp-8]ldr x0, [x29, #-8]ARM64: separate load instruction
Store to memorymov [rbp-8], raxstr x0, [x29, #-8]ARM64: separate store instruction
Load effective addresslea rax, [rip+label]adr x0, labelPC-relative; ARM64 also has adrp
Zero-extend byte loadmovzx eax, byte [rbp-1]ldrb w0, [x29, #-1]
Sign-extend byte loadmovsx rax, byte [rbp-1]ldrsb x0, [x29, #-1]
Push to stackpush raxstr x0, [sp, #-16]!ARM64 often uses stp for pairs
Pop from stackpop raxldr x0, [sp], #16ARM64 often uses ldp for pairs
Conditional movecmovz rax, rbxcsel x0, x1, x0, eqARM64 csel selects between two registers
Load pair— (no equivalent)ldp x0, x1, [sp]ARM64 can load/store two registers at once

2. Arithmetic

x86-64 typically uses a two-operand form (where the destination is also a source), while ARM64 uses a three-operand form (separate destination, source1, source2), allowing for more expressive single instructions.

Operationx86-64ARM64Notes
Addadd rax, rbxadd x0, x0, x1ARM64: 3-operand (dst, src1, src2)
Add with carryadc rax, rbxadc x0, x0, x1
Subtractsub rax, rbxsub x0, x0, x1
Subtract with borrowsbb rax, rbxsbc x0, x0, x1
Multiply (low result)imul rax, rbxmul x0, x1, x2x86-64 two-operand form; result truncated
Multiply highmul rbxRDX:RAXumulh x0, x1, x2x86-64: unsigned (mul) and signed (imul)
Multiply-accumulate— (no single instruction)madd x0, x1, x2, x3x0 = x1 × x2 + x3
Divide (signed)idiv rbxsdiv x0, x1, x2x86-64: divides RDX:RAX, result in RAX
Divide (unsigned)div rbxudiv x0, x1, x2x86-64: remainder in RDX
Negateneg raxneg x0, x1
Incrementinc raxadd x0, x0, #1ARM64 has no dedicated inc/dec
Decrementdec raxsub x0, x0, #1

3. Logic & Bitwise Operations

ARM64 includes efficient bit-manipulation instructions like bic (bit clear) and clz (count leading zeros) as single operations.

Operationx86-64ARM64Notes
Bitwise ANDand rax, rbxand x0, x0, x1
Bitwise ORor rax, rbxorr x0, x0, x1ARM64 mnemonic is orr
Bitwise XORxor rax, rbxeor x0, x0, x1ARM64 mnemonic is eor
Bitwise NOTnot raxmvn x0, x1ARM64: MoVe Not
Bit clear (AND NOT)andn rax, rbx, rcxbic x0, x1, x2x86-64: rax = (~rbx) AND rcx (BMI1)
Logical shift leftshl rax, cllsl x0, x1, x2
Logical shift rightshr rax, cllsr x0, x1, x2
Arithmetic shift rightsar rax, clasr x0, x1, x2Preserves sign bit
Rotate rightror rax, clror x0, x1, x2
Count leading zeroslzcnt rax, rbxclz x0, x1x86-64 requires LZCNT extension
Test bit + branchbt rax, 5 + jc labeltbnz x0, #5, labelx86-64: two instructions; ARM64: fused

4. Comparison & Branching

ARM64’s cbz and cbnz instructions combine compare-with-zero and branch into a single atomic operation, reducing instruction count in common loops and checks.

Operationx86-64ARM64Notes
Comparecmp rax, rbxcmp x0, x1Sets flags (SUB without storing)
Testtest rax, rbxtst x0, x1AND without storing
Branch if equalje labelb.eq label
Branch if not equaljne labelb.ne label
Branch if less (signed)jl labelb.lt label
Branch if greater (signed)jg labelb.gt label
Branch if ≤ (signed)jle labelb.le label
Branch if ≥ (signed)jge labelb.ge label
Branch if below (unsigned)jb labelb.lo labelCarry flag / unsigned
Branch if above (unsigned)ja labelb.hi label
Unconditional jumpjmp labelb label
Branch if zerotest rax, rax + je labelcbz x0, labelARM64 fuses test+branch
Branch if nonzerotest rax, rax + jne labelcbnz x0, label
Call functioncall funcbl funcARM64: return address in X30 (LR)
Returnretretx86-64 pops from stack; ARM64 uses X30

5. System Interface

System calls use different instructions and register conventions. ARM64 also provides explicit spin-loop hints like yield.

Operationx86-64ARM64Notes
System callsyscallsvc #0Syscall # in RAX vs X8
Breakpointint3brk #0Used by debuggers
No operationnopnop
Memory barriermfencedmb syARM64 has finer-grained barriers
Halt / YieldpauseyieldSpin-loop hint

Key Architectural Differences

Understanding these fundamental differences helps when reading this x86-64 ARM64 instruction map and translating between architectures:

Fixed vs. Variable-Length Instructions: ARM64 uses fixed 32-bit (4-byte) instructions, making disassembly trivial — every instruction starts at a 4-byte boundary. x86-64 instructions vary from 1 to 15 bytes, requiring sequential decoding from a known starting point.

Load-Store Architecture: ARM64 arithmetic operates only on registers. To add a value from memory, you must first ldr it into a register, then add. x86-64 can embed memory operands directly: add rax, [rbp-8].

Link Register vs. Stack Return: On ARM64, bl (branch with link) stores the return address in X30 (LR), and ret branches to X30. On x86-64, call pushes the return address onto the stack, and ret pops it. This means ARM64 leaf functions don’t need to save LR or set up a stack frame, though they may still use stack space for local variables.

Condition Codes: Both architectures set flags after certain operations, but ARM64 requires explicit flag-setting variants (adds, subs) for arithmetic — plain add/sub do not set flags. On x86-64, most arithmetic instructions always update RFLAGS.

PC-Relative Addressing: ARM64’s adrp/add pair can reach any address within ±4 GB of the current PC, while x86-64’s RIP-relative addressing reaches ±2 GB. Both are used for position-independent code.


How to Use This Map

This comparison maps the most common assembly instructions between the two dominant 64-bit architectures side by side. Use it as a translation table when:

  • Reading disassembly: Identify equivalent logic across architectures.
  • Porting code: Rewrite core logic for a different platform.
  • Studying compiler output: Understand how different backends lower the same high-level code.

Keep in mind that some mappings are not 1:1 — x86-64’s CISC heritage means a single instruction (like push) may require two ARM64 instructions (a subtract and a store). Conversely, ARM64 offers fused operations like madd (multiply-accumulate) and cbz (compare-and-branch) that require multiple x86-64 instructions.


Deep Dives

Cheat Sheets & References

Official Manuals

Coder Musings

A modern technical laboratory for systems programming. Master Assembly, Compilers, and Low-Level Engineering through curated paths and interactive visualizations.

© 2026 Coder Musings. All rights reserved. Built for the systems community.