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. Each row shows the equivalent operation with key differences noted.

For hands-on tutorials, see our Assembly Syscall Deep Dive (Linux/macOS, both architectures) and Calling Conventions Demystified. The authoritative references are the Intel Software Developer’s Manual and the ARM Architecture Reference Manual.

Data Movement in This x86-64 vs ARM64 Instruction Map

The biggest difference: ARM64 is a load-store architecture — arithmetic instructions cannot access memory directly. x86-64 allows memory operands in most instructions. This x86-64 ARM64 instruction map starts with data movement because it is the most frequent operation category.

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 register pairs
Pop from stackpop raxldr x0, [sp], #16ARM64 often uses ldp for register 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

Arithmetic

Arithmetic instructions are largely analogous, but x86-64 uses two-operand form (destination is also a source) while ARM64 uses three-operand form (separate destination).

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 to register width
Multiply highmul rbx → RDX:RAXumulh x0, x1, x2x86-64: unsigned (mul) and signed (imul) one-operand forms; ARM64: separate smulh/umulh
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

Logic & Bitwise Operations

Logical operations map almost directly. ARM64 adds bic (bit clear = AND NOT) and eon (exclusive OR NOT) as single instructions.

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, rcx (BMI1)bic x0, x1, x2x86-64: rax = (~rbx) AND rcx; ARM64: x0 = x1 AND (~x2) — NOT applied to opposite source
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 test-and-branch

Comparison & Branching

Both architectures use condition flags (RFLAGS / PSTATE). The conditional branch mnemonics differ but map to the same conditions. ARM64’s cbz/cbnz combine compare-with-zero and branch into a single instruction.

Operationx86-64ARM64Notes
Comparecmp rax, rbxcmp x0, x1Sets flags (SUB without storing)
Test (AND without storing)test rax, rbxtst x0, x1
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

System Interface

System calls use different instructions and register conventions on each architecture. The syscall number register and argument registers differ — refer to the Calling Conventions Cheat Sheet for the full register mapping.

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 for HyperThreading / SMT

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 x86-64 ARM64 Instruction Map

This x86-64 ARM64 instruction map is designed as a quick-lookup reference. When you encounter an unfamiliar instruction in disassembly output, find its row in the relevant table to see the equivalent on the other architecture. For deeper context on how these instructions interact with calling conventions and stack frames, see the related resources below.

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.

Related Resources

Deep dives: Assembly Hello World: Cross-Platform Syscall Tutorial | Calling Conventions Demystified | Stack Frames & Function Prologues

Also see: Calling Conventions Cheat Sheet | Assembly Directives Reference | Systems Programming Glossary

Official references: Intel SDM | ARM Architecture Reference Manual

Scroll to Top