Registers
arm64AArch64 Registers
ARM64 provides 31 general-purpose registers (X0–X30) with 32-bit W-aliases, plus SP, LR, PC, and PSTATE — each with a defined ABI role.
AArch64 (ARM64) defines 31 general-purpose registers plus several special-
purpose registers. All GPRs are 64 bits wide; their 32-bit aliases begin with
W.
General-purpose registers
| 64-bit | 32-bit | ABI role |
|---|---|---|
X0 | W0 | Argument 1 / Return value |
X1 | W1 | Argument 2 / Return value (2nd word) |
X2 | W2 | Argument 3 |
X3 | W3 | Argument 4 |
X4 | W4 | Argument 5 |
X5 | W5 | Argument 6 |
X6 | W6 | Argument 7 |
X7 | W7 | Argument 8 |
X8 | W8 | Indirect result location (struct return pointer) |
X9–X15 | W9–W15 | Temporary / caller-saved |
X16 | W16 | Intra-procedure-call scratch (IP0) |
X17 | W17 | Intra-procedure-call scratch (IP1) |
X18 | W18 | Platform register (reserved on some OSes) |
X19–X28 | W19–W28 | Callee-saved |
X29 | W29 | Frame pointer (FP) |
X30 | W30 | Link register (LR) — return address |
Special-purpose registers
| Name | Width | Description |
|---|---|---|
SP | 64-bit | Stack pointer (not a GPR — cannot be used as general operand) |
LR (X30) | 64-bit | Link register — holds return address set by BL/BLR |
PC | 64-bit | Program counter — not directly readable as a GPR (use ADR) |
XZR / WZR | — | Zero register — reads as 0, writes discarded |
PSTATE | — | Process State (condition flags N/Z/C/V, SP select, etc.) |
W-register write behaviour
Writing a W register zero-extends into the full X register — identical to
the x86-64 32-bit write rule. W0 = 0xFF → X0 = 0x00000000000000FF.
Reverse-engineering notes
X30(LR) is the return address on ARM64 — there is no hardware "return address on the stack" mechanism. Functions that call other functions must save LR to the stack in their prologue (STP X29, X30, [SP, #-16]!).X16/X17(IP0/IP1) are used by the linker for PLT/veneers — treating them as scratch in hand-written assembly is safe, but they may be clobbered between aBLand its target.X8as the indirect result register: when a function returns a large struct, the caller passes a pointer inX8and the callee writes the struct there. Decompilers sometimes miss this, making the return type look void.XZRappearing as a source is always zero; as a destination it discards the result — a common way to call an instruction purely for its flags effect (e.g.ADDS XZR, X0, X1sets flags without storing the sum).