Article by Ayman Alheraki on January 11 2026 10:34 AM
Apple’s M Series processors, including the M1, M1 Pro, M1 Max, M1 Ultra, and M2, are based on the ARM64 architecture. ARM processors use a Reduced Instruction Set Computing (RISC) architecture, and the M Series chips follow the ARMv8-A architecture (or later), which supports the 64-bit instruction set. Understanding the ARM64 registers is essential for working with low-level programming on these chips.
The ARM64 architecture has different types of registers for handling various tasks. These include general-purpose registers, special-purpose registers, and floating-point registers. Below is a detailed description of each type of register used in ARM64 along with tables that declare them.
In ARM64, there are 31 general-purpose registers, typically used for holding data, pointers, and addresses. These registers are 64 bits wide and are named X0 to X30. Each register can also be accessed in a 32-bit form, named W0 to W30, for operations that need less data.
X0 to X30: These are 64-bit registers used for integer operations, addresses, and general data storage.
W0 to W30: These are the 32-bit low halves of the 64-bit registers, used for operations requiring 32-bit data.
Additionally, ARM64 has a special-purpose general register called the Zero Register, which behaves differently based on how it’s used:
XZR: The 64-bit zero register always returns zero when read from.
WZR: The 32-bit zero register is the 32-bit version, also always returning zero.
| Register | 64-bit Name | 32-bit Name | Description |
|---|---|---|---|
| X0 | X0 | W0 | First argument or return value |
| X1 | X1 | W1 | Second argument or return value |
| X2 | X2 | W2 | Third argument |
| X3 | X3 | W3 | Fourth argument |
| X4 | X4 | W4 | Fifth argument |
| X5 | X5 | W5 | Sixth argument |
| X6 | X6 | W6 | Seventh argument |
| X7 | X7 | W7 | Eighth argument |
| X8 | X8 | W8 | Indirect result location or scratch |
| X9 | X9 | W9 | Temporary/scratch register |
| X10 | X10 | W10 | Temporary/scratch register |
| X11 | X11 | W11 | Temporary/scratch register |
| X12 | X12 | W12 | Temporary/scratch register |
| X13 | X13 | W13 | Temporary/scratch register |
| X14 | X14 | W14 | Temporary/scratch register |
| X15 | X15 | W15 | Temporary/scratch register |
| X16 | X16 | W16 | Intra-Procedure-call scratch (IP0) |
| X17 | X17 | W17 | Intra-Procedure-call scratch (IP1) |
| X18 | X18 | W18 | Platform-specific (e.g., TLS pointer) |
| X19 | X19 | W19 | Callee-saved register |
| X20 | X20 | W20 | Callee-saved register |
| X21 | X21 | W21 | Callee-saved register |
| X22 | X22 | W22 | Callee-saved register |
| X23 | X23 | W23 | Callee-saved register |
| X24 | X24 | W24 | Callee-saved register |
| X25 | X25 | W25 | Callee-saved register |
| X26 | X26 | W26 | Callee-saved register |
| X27 | X27 | W27 | Callee-saved register |
| X28 | X28 | W28 | Callee-saved register |
| X29 | X29 | W29 | Frame pointer (FP) |
| X30 | X30 | W30 | Link register (LR) |
| XZR | XZR | WZR | Zero register |
ARM64 also includes a number of special-purpose registers used for specific tasks like managing the program flow, memory access, and system control. Some of the key special-purpose registers are:
SP (Stack Pointer): Points to the top of the stack in memory. The stack is used for storing local variables and managing function calls.
PC (Program Counter): Holds the address of the next instruction to be executed.
FP (Frame Pointer): Typically used to maintain a stable reference point in the stack for local variables and function arguments.
LR (Link Register): Stores the return address for function calls.
| Register | Description |
|---|---|
| SP | Stack Pointer, points to the top of the current stack |
| PC | Program Counter, holds the next instruction address |
| FP | Frame Pointer, used to manage stack frames |
| LR | Link Register, stores the return address for functions |
The M series ARM64 architecture includes 32 floating-point registers, labeled V0 to V31. These registers are 128 bits wide and are used for both floating-point and SIMD (Single Instruction Multiple Data) operations. SIMD is used in vectorized operations, where a single instruction operates on multiple data points, enabling higher performance in tasks like multimedia processing, scientific computations, and cryptography.
Each floating-point register can be accessed in different widths depending on the operation:
Vn: Full 128-bit register.
Dn: 64-bit subset of the V register.
Sn: 32-bit subset of the V register.
Hn: 16-bit subset of the V register.
| Register | 128-bit Name | 64-bit Name | 32-bit Name | 16-bit Name | Description |
|---|---|---|---|---|---|
| V0 | V0 | D0 | S0 | H0 | Floating-point/SIMD register 0 |
| V1 | V1 | D1 | S1 | H1 | Floating-point/SIMD register 1 |
| V2 | V2 | D2 | S2 | H2 | Floating-point/SIMD register 2 |
| V3 | V3 | D3 | S3 | H3 | Floating-point/SIMD register 3 |
| V4 | V4 | D4 | S4 | H4 | Floating-point/SIMD register 4 |
| V5 | V5 | D5 | S5 | H5 | Floating-point/SIMD register 5 |
| V6 | V6 | D6 | S6 | H6 | Floating-point/SIMD register 6 |
| V7 | V7 | D7 | S7 | H7 | Floating-point/SIMD register 7 |
| V8 | V8 | D8 | S8 | H8 | Floating-point/SIMD register 8 |
| V9 | V9 | D9 | S9 | H9 | Floating-point/SIMD register 9 |
| V10 | V10 | D10 | S10 | H10 | Floating-point/SIMD register 10 |
| V11 | V11 | D11 | S11 | H11 | Floating-point/SIMD register 11 |
| V12 | V12 | D12 | S12 | H12 | Floating-point/SIMD register 12 |
| V13 | V13 | D13 | S13 | H13 | Floating-point/SIMD register 13 |
| V14 | V14 | D14 | S14 | H14 | Floating-point/SIMD register 14 |
| V15 | V15 | D15 | S15 | H15 | Floating-point/SIMD register 15 |
| V16 | V16 | D16 | S16 | H16 | Floating-point/SIMD register 16 |
| V17 | V17 | D17 | S17 | H17 | Floating-point/SIMD register 17 |
| V18 | V18 | D18 | S18 | H18 | Floating-point/SIMD register 18 |
| V19 | V19 | D19 | S19 | H19 | Floating-point/SIMD register 19 |
| V20 | V20 | D20 | S20 | H20 | Floating-point/SIMD register 20 |
| V21 | V21 | D21 | S21 | H21 | Floating-point/SIMD register 21 |
| V22 | V22 | D22 | S22 | H22 | Floating-point/SIMD register 22 |
| V23 | V23 | D23 | S23 | H23 | Floating-point/SIMD register 23 |
| V24 | V24 | D24 | S24 | H24 | Floating-point/SIMD register 24 |
| V25 | V25 | D25 | S25 | H25 | Floating-point/SIMD register 25 |
| V26 | V26 | D26 | S26 | H26 | Floating-point/SIMD register 26 |
| V27 | V27 | D27 | S27 | H27 | Floating-point/SIMD register 27 |
| V28 | V28 | D28 | S28 | H28 | Floating-point/SIMD register 28 |
| V29 | V29 | D29 | S29 | H29 | Floating-point/SIMD register 29 |
| V30 | V30 | D30 | S30 | H30 | Floating-point/SIMD register 30 |
| V31 | V31 | D31 | S31 | H31 | Floating-point/SIMD register 31 |
ARM64 also includes system control registers, used for managing the operating environment, controlling caches, enabling exceptions, and more. These registers are typically accessible only in privileged (kernel or supervisor) modes.
Examples of system control registers include:
SCTLR (System Control Register): Controls cache, memory alignment, and other system features.
TTBR (Translation Table Base Register): Stores the base address of page tables for memory management.
ESR (Exception Syndrome Register): Holds information about the cause of an exception.
The ARM64 architecture in Apple’s M Series chips provides a set of powerful registers, each designed to optimize the handling of data, memory addresses, floating-point operations, and system control. Understanding these registers is key to effectively programming low-level applications or performing optimizations for Apple Silicon-powered devices.