common instruction families (mov, add, cmp, jmp, call, ret)
An ISA may list hundreds of instructions, but a surprisingly small handful does most of the work in ordinary compiled code. Group them by job and almost any disassembly becomes readable. Think of them as a few families: data movement, arithmetic, comparison, control flow, calls, and stack moves.
The everyday families are these. Data movement: mov copies a value between registers and memory; on a load-store machine like ARM the same job is split into load (ldr) and store (str). Arithmetic and logic: add, sub, mul, and the bitwise and, or, xor, shl/shr run the actual computation. Comparison: cmp subtracts to set the flags without keeping the result, and test does a bitwise AND for the same purpose. Control flow: jmp is an unconditional jump, while the conditional branches (je, jne, jl, jg, and so on) jump only when the flags say so — these are how if and loops are built. Calls: call jumps to a function while pushing a return address, and ret pops that address to jump back. Stack moves: push puts a value on the stack and pop takes one off.
Learn these six families and you can follow the skeleton of almost any function: movs shuffle data into place, an add or sub does the work, a cmp followed by a conditional jump makes a decision, a call invokes a helper, push/pop save and restore values around it, and a ret hands control back. Everything else is variation and detail layered on this small, recurring vocabulary.
if (a == b) f(); compiles to roughly: cmp eax, ebx / jne skip / call f / skip: — compare, branch on the flags, and conditionally call.
A few families — move, arithmetic, compare, branch, call/ret, push/pop — cover most compiled code.
Mnemonic names differ by ISA: x86-64 says mov/jmp/call, AArch64 says mov/ldr/str/b/bl, but the families map across. Note that cmp and test deliberately throw away their result — their only purpose is the side effect of setting the flags for the branch that follows.