ARM assembly overview, Summaries of Computer science

ARM assembly overview summary document

Typology: Summaries

2025/2026

Uploaded on 03/29/2026

boris-karloff-1
boris-karloff-1 ๐Ÿ‡ฌ๐Ÿ‡ง

9 documents

1 / 7

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
ARM / AArch64 Assembly Reference Student Edition
ARM / AArch64 Assembly Language
Introductory Reference โ€” Registers, Instructions & Addressing
Two architectures covered. ARM has two main assembly variants in common use: AArch64 /
A64 (64-bit, used in modern phones, Apple Silicon, Raspberry Pi 4+) and AArch32 / A32 (ARM)
(32-bit, found in older embedded systems and Raspberry Pi 2/3 in 32-bit mode). This document
covers both, noting differences where they exist.
1. Registers
1.1 AArch64 General-Purpose Registers (64-bit)
AArch64 has 31 general-purpose registers. Each can be addressed as a 64-bit register (Xn) or its
lower 32-bit half (Wn). Writing to Wn automatically zeroes the upper 32 bits.
Register 32-bit alias Conventional use
X0โ€“X7 W0โ€“W7 Arguments / return values. X0 = 1st arg & return value.
X8 W8 Indirect result location register (syscall number on Linux).
X9โ€“X15 W9โ€“W15 Caller-saved temporaries โ€” free to use, not preserved across calls.
X16โ€“X17 W16โ€“W17 Intra-procedure-call scratch (IP0, IP1) โ€” used by linker veneers.
X18 W18 Platform register (reserved on Windows; general use on Linux).
X19โ€“X28 W19โ€“W28 Callee-saved โ€” must be preserved across function calls.
X29 W29 Frame pointer (FP) โ€” base of the current stack frame.
X30 W30 Link register (LR) โ€” holds return address after a BL/BLR call.
SP WSP Stack pointer โ€” must be 16-byte aligned at public interfaces.
XZR / WZR โ€” Zero register โ€” reads always return 0; writes are discarded.
PC โ€” Program counter โ€” not directly readable/writable in most
instructions.
1.2 AArch64 Special-Purpose Registers
Register Purpose
NZCV Condition flags: Negative, Zero, Carry, oVerflow โ€” ARM equivalent of x86
RFLAGS (relevant subset).
FPCR Floating-Point Control Register โ€” rounding mode, exception enable bits.
FPSR Floating-Point Status Register โ€” cumulative exception flags.
V0โ€“V31 128-bit SIMD/FP registers. Also accessed as D0โ€“D31 (64-bit), S0โ€“S31 (32-bit),
H0โ€“H31 (16-bit), B0โ€“B31 (8-bit).
ELR_ELn Exception Link Register โ€” saves PC on exception entry.
SPSel Selects between SP_EL0 and SP_ELn for the current exception level.
pf3
pf4
pf5

Partial preview of the text

Download ARM assembly overview and more Summaries Computer science in PDF only on Docsity!

ARM / AArch64 Assembly Language

Introductory Reference โ€” Registers, Instructions & Addressing

Two architectures covered. ARM has two main assembly variants in common use: AArch64 /

A64 (64-bit, used in modern phones, Apple Silicon, Raspberry Pi 4+) and AArch32 / A32 (ARM)

(32-bit, found in older embedded systems and Raspberry Pi 2/3 in 32-bit mode). This document

covers both, noting differences where they exist.

1. Registers 1.1 AArch64 General-Purpose Registers (64-bit)

AArch64 has 31 general-purpose registers. Each can be addressed as a 64-bit register (Xn) or its

lower 32-bit half (Wn). Writing to Wn automatically zeroes the upper 32 bits.

Register 32-bit alias Conventional use X0โ€“X7 (^) W0โ€“W7 Arguments / return values. X0 = 1st arg & return value. X8 (^) W8 Indirect result location register (syscall number on Linux). X9โ€“X15 (^) W9โ€“W15 Caller-saved temporaries โ€” free to use, not preserved across calls. X16โ€“X17 (^) W16โ€“W17 Intra-procedure-call scratch (IP0, IP1) โ€” used by linker veneers. X18 (^) W18 Platform register (reserved on Windows; general use on Linux). X19โ€“X28 (^) W19โ€“W28 Callee-saved โ€” must be preserved across function calls. X29 (^) W29 Frame pointer (FP) โ€” base of the current stack frame. X30 (^) W30 Link register (LR) โ€” holds return address after a BL/BLR call. SP (^) WSP Stack pointer โ€” must be 16-byte aligned at public interfaces. XZR / WZR (^) โ€” Zero register โ€” reads always return 0; writes are discarded. PC (^) โ€” Program counter โ€” not directly readable/writable in most instructions. 1.2 AArch64 Special-Purpose Registers Register Purpose NZCV (^) Condition flags: Negative, Zero, Carry, oVerflow โ€” ARM equivalent of x RFLAGS (relevant subset). FPCR (^) Floating-Point Control Register โ€” rounding mode, exception enable bits. FPSR (^) Floating-Point Status Register โ€” cumulative exception flags. V0โ€“V31 (^) 128-bit SIMD/FP registers. Also accessed as D0โ€“D31 (64-bit), S0โ€“S31 (32-bit), H0โ€“H31 (16-bit), B0โ€“B31 (8-bit). ELR_ELn (^) Exception Link Register โ€” saves PC on exception entry. SPSel (^) Selects between SP_EL0 and SP_ELn for the current exception level.

1.3 AArch32 Registers (32-bit ARM / Thumb) Register Alias Role R0โ€“R3 (^) a1โ€“a4 Arguments and return values (R0 = 1st arg / return). R4โ€“R11 (^) v1โ€“v8 Callee-saved variable registers. R11 (^) FP Frame pointer (compiler-dependent). R12 (^) IP Intra-procedure-call scratch register. R13 (^) SP Stack pointer. R14 (^) LR Link register โ€” return address stored here by BL. R15 (^) PC Program counter โ€” readable and writable (use with care). CPSR (^) โ€” Current Program Status Register โ€” holds N, Z, C, V flags plus mode bits.

2. Addressing Modes

ARM uses a load/store architecture: only dedicated load (LDR) and store (STR) instructions

access memory. All arithmetic operates on registers only. This contrasts with x86 where most

instructions can directly read from or write to memory.

2.1 AArch64 Load/Store Addressing Mode Syntax Meaning Base register (^) LDR X0, [X1] Load from address in X1 (offset = 0). Base + immediate offset LDR X0, [X1, #16] Load from X1 + 16. X1 unchanged (offset addressing). Pre-indexed (^) LDR X0, [X1, #16]! X1 = X1 + 16 first, then load from new X1. Post-indexed (^) LDR X0, [X1], #16 Load from X1, then X1 = X1 + 16. Base + register offset LDR X0, [X1, X2] Load from X1 + X2. Scaled register offset LDR X0, [X1, X2, LSL #3] Load from X1 + (X2 << 3) โ€” useful for array indexing. PC-relative literal LDR X0, =label Load 64-bit value from a literal pool near the label (assembler generates the pool). Pair (^) LDP X0, X1, [SP, #16] Load two consecutive registers in one instruction. 2.2 Shifted / Extended Register Operands

In arithmetic and logical instructions, the second source register can be optionally shifted or

extended before use โ€” no extra instruction required.

Modifier Example Effect on Rm before operation LSL #n (^) ADD X0, X1, X2, LSL #2 Logical shift left by n bits (multiply by 2^n). LSR #n (^) SUB X0, X1, X2, LSR #1 Logical shift right by n bits (unsigned divide

Instruction Example Effect MSUB Xd, Xn, Xm, Xa (^) MSUB X3, X1, X2, X0 Xd = Xa - Xn*Xm. After SDIV: MSUB gives remainder. NEG Xd, Xn (^) NEG X0, X1 Xd = 0 - Xn (two's complement negation). ADC / SBC (^) ADC X0, X1, X2 Add / subtract with carry โ€” for multi- precision arithmetic. 3.3 Bitwise & Shift Instruction Example Effect AND Xd, Xn, Xm/#imm (^) AND X0, X0, #0xFF Bitwise AND โ€” mask bits. ORR Xd, Xn, Xm/#imm (^) ORR X0, X0, #0x1 Bitwise OR โ€” set bits. (ARM uses ORR not OR.) EOR Xd, Xn, Xm/#imm (^) EOR X0, X0, X0 Bitwise XOR. EOR Xd, Xn, Xn zeroes Xd. BIC Xd, Xn, Xm (^) BIC X0, X0, X1 Bit clear: Xd = Xn AND NOT Xm. MVN Xd, Xn (^) MVN X0, X1 Bitwise NOT (move negated). LSL Xd, Xn, #n/Xm (^) LSL X0, X1, #3 Logical shift left. LSR Xd, Xn, #n/Xm (^) LSR X0, X1, #1 Logical shift right (zero-fills). ASR Xd, Xn, #n/Xm (^) ASR X0, X1, #1 Arithmetic shift right (sign-extends). ROR Xd, Xn, #n/Xm (^) ROR X0, X1, #8 Rotate right. CLZ Xd, Xn (^) CLZ X0, X1 Count leading zeros โ€” useful for normalisation. 3.4 Control Flow Instruction Example Effect B label (^) B loop Unconditional branch (PC-relative, ยฑ128 MB). BL label (^) BL my_func Branch with link โ€” saves PC+4 into LR, then jumps. BR Xn (^) BR X16 Branch to address in register (indirect jump). BLR Xn (^) BLR X0 Branch with link to address in register (indirect call). RET (^) RET Return: branch to address in X30 (LR). RET Xn (^) RET X8 Return to address in specified register. B.cond label (^) B.EQ done Conditional branch based on NZCV flags (see conditions below). CBZ Xn, label (^) CBZ X0, skip Branch if Xn == 0 (compare and branch zero โ€” no flags needed). CBNZ Xn, label (^) CBNZ X0, loop Branch if Xn != 0. TBZ Xn, #bit, l (^) TBZ X0, #3, skip Branch if bit N of Xn is zero. TBNZ Xn, #bit, l (^) TBNZ X0, #0, odd Branch if bit N of Xn is non-zero.

3.5 Condition Codes

Used as suffixes on B (e.g. B.EQ) and on conditional instructions like CSEL, CSET.

Code Meaning Flags tested Opposite EQ (^) Equal Z=1 NE NE (^) Not equal Z=0 EQ CS / HS (^) Carry set / unsigned higher or same

C=1 CC / LO

CC / LO (^) Carry clear / unsigned lower C=0 CS / HS MI (^) Minus / negative N=1 PL PL (^) Plus / positive or zero N=0 MI VS (^) Overflow set V=1 VC VC (^) Overflow clear V=0 VS HI (^) Unsigned higher C=1 and Z=0 LS LS (^) Unsigned lower or same C=0 or Z=1 HI GE (^) Signed greater or equal N=V LT LT (^) Signed less than N!=V GE GT (^) Signed greater than Z=0 and N=V LE LE (^) Signed less or equal Z=1 or N!=V GT AL (^) Always (unconditional) โ€” โ€” 3.6 Conditional Instructions Instruction Example Effect CSEL Xd, Xn, Xm, cond (^) CSEL X0, X1, X2, EQ Xd = (cond true)? Xn : Xm โ€” conditional select, no branch. CSET Xd, cond (^) CSET X0, GE Xd = (cond true)? 1 : 0 โ€” set register to boolean. CSINC Xd, Xn, Xm, cond (^) CSINC X0, X1, XZR, NE Xd = (cond true)? Xn : Xm+1. CSINC Xd,XZR,XZR,NE sets 0 or 1. CINC Xd, Xn, cond (^) CINC X0, X0, EQ Xd = (cond true)? Xn+1 : Xn โ€” conditional increment. CNEG Xd, Xn, cond (^) CNEG X0, X1, LT Xd = (cond true)? -Xn : Xn โ€” conditional negate.

4. Calling Convention โ€” AAPCS

The Procedure Call Standard for AArch64 (AAPCS64) is used on Linux, macOS, and Windows

ARM64.

Notation: Xd = destination register, Xn / Xm = source registers, #imm = immediate constant, [ ] = memory address,! = writeback (pre-index), cond = condition code suffix. AArch64 (A64) syntax used throughout.