Machine Instructions and Registers
The processor does not execute C
Section titled “The processor does not execute C”A compiler translates C into machine instructions encoded as bytes. Assembly language is the human-readable notation tools use for those instructions. Disassembly works in the opposite direction: it decodes bytes into assembly text, but it does not restore the original variable names, comments, or programmer intent.
Create decision.c:
#include <stdio.h>
int classify(int value) { if (value > 10) { return value + 2; } return value - 2;}
int main(void) { printf("%d\n", classify(12)); return 0;}Compile it with optimizations disabled so the output stays easier to follow:
gcc -O0 -g -o decision decision.cobjdump -d -Mintel decision | lessSearch inside less by typing /<classify> and pressing Enter. Press q when finished.
Read one instruction at a time
Section titled “Read one instruction at a time”An instruction line contains an address, encoded bytes, a mnemonic, and operands. In Intel syntax, common instructions include:
| Instruction | Useful first interpretation |
|---|---|
mov destination, source |
Copy a value |
add destination, source |
Add into the destination |
sub destination, source |
Subtract from the destination |
cmp left, right |
Compare by setting processor flags |
jmp target |
Continue at another instruction |
jle, jg, and relatives |
Branch when a condition represented by flags is true |
call target |
Transfer control to a function while preserving a return location |
ret |
Return to the saved location |
Registers such as rax, rbp, rsp, and rdi are named storage locations in the x86-64 processor. Some names refer to smaller portions of a register: eax is the low 32 bits of rax.
Do not translate every mov into “assignment.” Compilers use moves for arguments, temporary values, saved state, and memory access. Follow where the value came from and where it goes.
Knowledge check
Question 1 of 2
Knowledge check complete
You answered all 2 questions correctly.
Trace the decision
Section titled “Trace the decision”Find the comparison with 10, then the conditional branch following it. Record:
- Where the function receives or stores
value. - Which instruction compares it with
10. - Which branch selects the
value + 2orvalue - 2path. - Which register holds the integer return value near
ret.
Change the call from classify(12) to classify(8), predict the output, recompile, and compare both behavior and disassembly. A source change may alter data without changing instruction structure.
Addresses and values are different jobs
Section titled “Addresses and values are different jobs”The number printed at the left of an instruction is where that instruction resides. An operand may itself be an immediate value, register, or memory address. Treating every hexadecimal number as “the address” is a reliable way to become lost.
When taking notes, label numbers by role: instruction address, branch target, constant, register value, or memory address. The labels are conclusions supported by context, not decoration.
What this gives us as researchers
Section titled “What this gives us as researchers”You can now reduce a small assembly function to data movement, arithmetic, a comparison, and a control-flow choice. Next we will examine what call and ret require from the stack.