**What is machine code?**
* Machine code is the raw binary (0s/1s) instructions a CPU executes.
* Each instruction is a fixed/variable number of bits and encodes an opcode (what to do) plus operands (registers, immediates, memory addresses).
* It’s architecture-specific (x86-64 vs ARM vs RISC-V have different encodings).
* Usually shown in hex for readability (e.g., 0x20080005).

**What is assembly language?**
* Assembly is a human-readable representation of machine code.
* Uses mnemonics (e.g., ADD, MOV, LDR) and symbols (labels like loop:) instead of raw bits.
* Adds directives (.data, .text), macros, and pseudo-instructions to make coding easier.
* Still architecture-specific and closely tied to the CPU’s ISA (instruction set architecture).
**How they relate (toolchain view)**
1. C/C++/Rust → (compiler) → assembly (optional visible step)
2. Assembly → (assembler) → object code (machine code + metadata/relocations)
3. Object files → (linker) → executable machine code
4. Disassembler can reverse machine code back to assembly (roughly).
**Side-by-side example (MIPS32, “add 5 + 7”)**
**Assembly**
addi $t0, $zero, 5 # t0 = 5
addi $t1, $zero, 7 # t1 = 7
add $t2, $t0, $t1 # t2 = t0 + t1 (=12)
**Machine code (hex words)**
```
0x20080005 # addi rt=$t0(8), rs=$zero(0), imm=5
0x20090007 # addi rt=$t1(9), rs=$zero(0), imm=7
0x01095020 # add rd=$t2(10), rs=$t0(8), rt=$t1(9), funct=0x20
```
(Note: actual byte order in memory depends on endianness.)
**Key differences (at a glance)**

**Why/when use assembly?**
* Tight control over registers, instructions, cache hints, SIMD.
* Critical hot paths where every cycle counts ([DSP](https://www.ampheo.com/c/dsp-digital-signal-processors), crypto kernels, ISR prologues).
* Startup code/bootloaders, context switches, embedded bare-metal.
* Teaching/diagnostics (reading disassembly to understand performance).
**Why not usually write machine code by hand?**
It’s error-prone and unreadable. Even assembly is hard to maintain; most projects use high-level languages and inspect compiler-generated assembly only when needed.
**Common extras you’ll see in assembly**
* Addressing modes (immediate, register, base+offset, indexed).
* Calling convention/ABI (which registers hold args/returns, who saves what).
* Assembler flavors (e.g., x86 [Intel](https://www.ampheo.com/manufacturer/intel) vs AT&T syntax).
* Directives like .globl, .align, .word, .section, etc.
**Handy tools**
* objdump / llvm-objdump: disassemble (objdump -d a.out)
* ndisasm / radare2 / Cutter / Ghidra: deeper inspection
* Compiler explorer (godbolt.org): see how high-level code maps to assembly