ARM Assembly Cheat Sheet
Instructions
-
Operation Syntax Semantic Flags Addition add{s} {Rd,} Rn, Rm {, shift} Rd(n) ≔ Rn + Rmshifted NZCV adc{s} {Rd,} Rn, Rm {, shift} Rd(n) ≔ Rn + Rmshifted + C NZCV add{s} {Rd,} Rn, #const Rd(n) ≔ Rn + const NZCV adc{s} {Rd,} Rn, #const Rd(n) ≔ Rn + const + C NZCV qadd {Rd,} Rn, Rm Rd(n) ≔ saturated(Rn + Rm) Q Subtraction sub{s} {Rd,} Rn, Rm {, shift} Rd(n) ≔ Rn − Rmshifted NZCV sbc{s} {Rd,} Rn, Rm {, shift} Rd(n) ≔ Rn − Rmshifted + C NZCV rsb{s} {Rd,} Rn, Rm {, shift} Rd(n) ≔ Rmshifted − Rn NZCV sub{s} {Rd,} Rn, #const Rd(n) ≔ Rn − const NZCV sbc{s} {Rd,} Rn, #const Rd(n) ≔ Rn − const + C NZCV rsb{s} {Rd,} Rn, #const Rd(n) ≔ const − Rn NZCV qsub{s} {Rd,} Rn, Rm Rd(n) ≔ saturated(Rn − Rm) Q Multiplication mul {Rd,} Rn, Rm Rd(n) ≔ Rn × Rm - mla Rd, Rn, Rm, Ra Rd ≔ Ra + (Rn × Rm) - mls Rd, Rn, Rm, Ra Rd ≔ Ra - (Rn × Rm) - umull RdLo, RdHi, Rn, Rm RdHi:RdLo ≔ (uint64) Rn × Rm - umlal RdLo, RdHi, Rn, Rm RdHi:RdLo ≔ (uint64) RdHi:RdLo + (Rn × Rm) - smull RdLo, RdHi, Rn, Rm RdHi:RdLo ≔ (int64) Rn × Rm - smlal RdLo, RdHi, Rn, Rm RdHi:RdLo ≔ (int64) RdHi:RdLo + (Rn × Rm) - Division udiv Rd, Rn, Rm Rd ≔ (uint32) Rn ÷ Rm (rounded to 0) - sdiv Rd, Rn, Rm Rd ≔ (int32) Rn ÷ Rm (rounded to 0) - -
Operation Syntax Semantic Flags Logic and{s} {Rd,} Rn, Rm {, shift} Rd(n) ≔ Rn ∧ Rmshifted NZCV bic{s} {Rd,} Rn, Rm {, shift} Rd(n) ≔ Rn ∧ ¬Rmshifted NZCV orr{s} {Rd,} Rn, Rm {, shift} Rd(n) ≔ Rn ∨ Rmshifted NZCV orn{s} {Rd,} Rn, Rm {, shift} Rd(n) ≔ Rn ∨ ¬Rmshifted NZCV eor{s} {Rd,} Rn, Rm {, shift} Rd(n) ≔ Rn ⊕ Rmshifted NZCV and{s} {Rd,} Rn, #const Rd(n) ≔ Rn ∧ const NZCV bic{s} {Rd,} Rn, #const Rd(n) ≔ Rn ∧ ¬const NZCV orr{s} {Rd,} Rn, #const Rd(n) ≔ Rn ∨ const NZCV orn{s} {Rd,} Rn, #const Rd(n) ≔ Rn ∨ ¬const NZCV eor{s} {Rd,} Rn, #const Rd(n) ≔ Rn ⊕ const NZCV Test cmp Rn, Rm {, shift} Rn − Rmshifted NZCV cmn Rn, Rm {, shift} Rn + Rmshifted NZCV tst Rn, Rm {, shift} Rn ∧ Rmshifted NZCV teq Rn, Rm {, shift} Rn ⊕ Rmshifted NZCV cmp Rn, #const Rn − const NZCV cmn Rn, #const Rn + const NZCV tst Rn, #const Rn ∧ const NZCV teq Rn, #const Rn ⊕ const NZCV -
Operation Syntax Semantic Flags Move mov{s} Rd, Rm Rd ≔ Rm NZ mov{s} Rd, #const Rd ≔ const NZC Shift/Rotate lsl{s} Rd, Rm, Rs Rd ≔ Rm << Rs NZC lsr{s} Rd, Rm, Rs Rd ≔ (uint32) Rm >> Rs NZC asr{s} Rd, Rm, Rs Rd ≔ (int32) Rm >> Rs NZC ror{s} Rd, Rm, Rs Rd ≔ Rm << (32 − Rs) ∨ Rm >> Rs NZC lsl{s} Rd, Rm, #const Rd ≔ Rm << const NZC lsr{s} Rd, Rm, #const Rd ≔ (uint32) Rm >> const NZC asr{s} Rd, Rm, #const Rd ≔ (int32) Rm >> const NZC ror{s} Rd, Rm, #const Rd ≔ Rm << (32 - const) ∨ Rm >> const NZC rrx{s} Rd, Rm Rd ≔ C << 31 ∨ Rm >> 1 NZC -
Operation Syntax Semantic Flags Offset ldr Rd, [Rb {, #const}] Rd ≔ [Rb + const] - str Rs, [Rb {, #const}] [Rb + const] ≔ Rs - Pre-offset ldr Rd, [Rb {, #const}]! Rb += const; Rd ≔ [Rb] - str Rs, [Rb {, #const}]! Rb += const; [Rb] ≔ Rs - Post-offset ldr Rd, [Rb], #const Rd ≔ [Rb]; Rb += const - str Rs, [Rb], #const [Rb] ≔ Rs; Rb += const - Indexed ldr Rd, [Rb, Ri {, LSL n}] Rd ≔ [Rb + (Ri << n)] - str Rs, [Rb, Ri {, LSL n}] [Rb + (Ri << n)] ≔ Rs - Literal ldr Rd, label Rd ≔ [label] - ldr Rd, [PC, #offset] Rd ≔ [PC + offset] - Positive stack stmia Rs!, registers for Ri in registers do [Rs] ≔ Ri; Rs += 4 - ldmdb Rs!, registers for Ri in rev(registers) do Rs -= 4; Ri ≔ [Rs] - Negative stack stmdb Rs!, registers for Ri in rev(registers) do Rs -= 4; [Rs] ≔ Ri - ldmia Rs!, registers for Ri in registers do Ri ≔ [Rs]; Rs += 4 - -
Operation Syntax Semantic Flags General b<c> label if c then PC ≔ label- bl label LR ≔ PCnext; PC ≔ label - bx Rm PC ≔ Rm - blx Rm LR ≔ PCnext; PC ≔ Rm - Test & branch cbz Rn, label if Rn = 0 then PC ≔ label - cbnz Rn, label if Rn ≠ 0 then PC ≔ label - Table based tbb [Rn, Rm] PC += (byte) [PC + Rm] - tbh [Rn, Rm {, LSL 1}] PC += (hword) [PC + Rm << shift] - <c>
denotes a condition suffix. For example, usebeq
to branch only when the zero flag is set. -
Syntax Semantic Flags ldrex Rd, [Rn {, #const}] Rd ≔ [Rn + const]; EX=True - strex Rt, Rs, [Rn {, #const}] if EX then [Rn + const] ≔ Rs; Rd ≔ 0 else Rd ≔ 1 - The synchronisation instructions work with a special "exclusive monitor" (denoted EX in the table) that tracks the "exclusive state" of the CPU.
- Every LDREX instruction will succeed and set the exclusive state to true.
- An STREX instruction will check the exclusive state, and if true, will execute the store, write 0 to Rd, and set the state to false. If the state was already false, the store is not executed and Rd is set to 1. This entire sequence is done atomically.
- A context switch (such as an interrupt) will set the exclusive state to false.
- Instructions with an optional
s
suffix will only change the flags if this suffix is added. - Optional constants and shifts default to 0 / no shift.
- Square brackets such as in
[Rd]
denote the memory stored at the given address, in this case the address held in Rd.
Shifts
Shift | Meaning | Description |
---|---|---|
LSL n | Logical shift left | Shift the bits left by \(n\), discarding the higher bits and filling the lower ones with 0 |
LSR n | Logical shift right | Shift the bits right by \(n\), filling the higher bits with 0 and discarding the lower ones |
ASR n | Arithmetic shift right | Shift the bits right by \(n\), filling the higher bits with copies of bit 15 and discarding the lower ones. This preserves the sign of a signed number |
ROR n | Rotate right | Rotate the bits right by \(n\), filling the higher bits with the lower bits being shifted out |
RRX | Rotate right with carry | Rotate the bits right by 1, filling bit 15 with the carry flag and discarding bit 0 |
Flags
Flag | Meaning | Description |
---|---|---|
N | Negative | The result, viewed as a two's complement signed number, is negative |
Z | Zero | The result equals 0 |
C | Carry | Instruction dependent. For addition, the result wrapped past 232 |
V | Overflow | Instruction dependent. For addition, the inputs have the same sign that is different than the results |
Q | Saturated | Signed overflow (result saturated) |
Conditions
Condition | Meaning | Flags |
---|---|---|
eq | Equal | Z = 1 |
ne | Not equal | Z = 0 |
cs, hs | Carry set, unsigned higher or same | C = 1 |
cc, lo | Carry clear, unsigned lower | C = 0 |
mi | Minus, negative | N = 1 |
pl | Plus, positive or zero | N = 0 |
vs | Overflow set | V = 1 |
vc | Overflow clear | V = 0 |
hi | Unsigned higher | C = 1 ∧ Z = 0 |
ls | Unsigned lower or same | C = 0 ∨ Z = 1 |
ge | Signed greater or equal | N = V |
lt | Signed less | N ≠ V |
gt | Signed greater | Z = 0 ∧ N = V |
le | Signed less or equal | Z = 1 ∨ N ≠ V |
al, <omit> | Always | any |
Width
Suffix | Meaning | Opcode width |
---|---|---|
.n | Narrow | 16 bits |
.w | Wide | 32 bits |
<omit> | Unset | Assembler decides |
The width is an optional suffix on the instruction name (after any condition).