Assembly
Tody, Sept 21, 2025, I’m learning assembly from Pwn.college.
Intro
Come on, Assembly is named “Assembly” because it is assembled (not compiled) into binary code.
The inventor is Kathleen Booth.
Assembly is the simplest programming language.
So You can master assembly in a week!
Assembly tells computer what to do, with a Noun/Operands, and Verbs/Operators.
There are tow syntaxes of x86 assembly, AT&T and Intel.
Data
Binary
A binary digit is called a bit
.
And a byte is a 8-bits group.
Then there’s word
here, first composed of 2bytes, then 4, and now 8bytes typically for modern computer.
Registers
Registers are very fast, temporary stores for data.
Registers are (typically) the same size as the word width of the architecture
Control Flow
Conditional jumps check Conditions stored in the “flags” register:
rflags
There is a bunch of bits in
rflags
, each indicates a “flag”.
Flags are updated by:
- Most arithmetic instructions
- Comparison instruction cmp(sub, but discards result)
- Comparison instruction test(and, but discards result)
Main conditional flags:
- Carry Flag: was the 65th bit 1?
- Zero Flag: was the result 0?
- Overflow Flag: did the result “wrap” between positive to negative?
- Signed Flag: was the result’s signed bit set (i.e, was it negative)?
Common patterns:
1 | cmp rax, rbx; ja STAY_LEET # unsigned rax > rbx. 0xffffffff >= 0 |
Function Calls
Assembly code is split into functions with call
and ret
.call
pushes rip
(address of the next instruction after the call) and jumps away!ret
pops rip
and jumps to it!
An example:
1 | int check_leet(int authed) { |
In assembly, it looks like this:
1 | noprefix |
Practicing
Set Registers
1 | mov dest_reg, src_reg |
Add to Registers
1 | add reg1, reg2 |
This means add reg2
to reg1
and store the sum in reg1
;
Linear Equation of Register
1 | imul reg1, reg2 |
This means reg4 = reg1 * reg2 + reg3
Integer Division
For the instruction div reg
, the following happens:
rax
=rdx:rax
/reg
rdx
=remainder
Access Lower Bits
We could access eht lower bytes of each register using different register names.
1 | MSB LSB |
Byte Extraction
Shifting has the nice side effect of doing quick multiplication (by2) or division (by2), and can also be used to compute modulo.
shl reg1, reg2
<=> Shiftreg1
left by the amount inreg2
shr reg1, reg2
<=> Shiftreg1
right by the amount inreg2
Bitwise Operation
We have four kinds of logic instructions to implement bitwise operation: and
, or
, not
, xor
.
Memory size access
The breakdown of the names of memory sizes:
- Quad Word = 8 Bytes = 64 bits
- Double Word = 4 Bytes = 32 bits
- Word = 2 bytes = 16 bits
- Byte = 1 Byte = 8 bits
Jump
Absolute Jump
1 | lea reg, [mem] |
Relative Jump
1 | jmp END |
This snippet does jmp to [0x50 + the_addr_of_jmp_END].
Indirect Jump
Here we do not jump directly to an address or a symbol, we could make a jump table
, look like:
1 | [0x1337] = address of do_thing_0 |
Here 0x1337
is the address of the jump table
, and we jump like this:
1 | jmp [jump_table_address + number * 0x8] |
This kind of jump always be used to write a switch
like snippet, looks like:
1 | switch(x) { |