What is assembly language and how does it relate to machine code?
Assembly is a human-readable, essentially one-to-one notation for machine code — each assembly instruction maps to one binary machine instruction.
Machine code is just bytes; assembly is those same bytes written with names. The mapping is direct:
add %rbx, %rax → 48 01 d8
mov $42, %eax → b8 2a 00 00 00
ret → c3
What assembly adds over raw bytes is purely for humans: readable mnemonics instead of opcodes, symbolic labels instead of numeric addresses, and comments. It's the level reverse engineers work at because it's the lowest level you can still read.
One practical wrinkle is that there are two syntaxes for the same x86 instructions:
| AT&T (GCC/GAS default) | Intel (NASM, Windows) |
|---|---|
mov %rax, %rbx |
mov rbx, rax |
| source, destination | destination, source |
% before registers |
bare register names |
$ before immediates |
bare numbers |
Knowing which syntax you're reading is essential — the operand order is reversed between them, so the same line means opposite things.
Go deeper:
Assembly language (Wikipedia) — the one-to-one mnemonic-to-machine-instruction mapping.