Assembly Language

Numerical Ranges

Unsigned Integers

Range: $[0, 2^n-1]$

Table:

Bits Largest HEX Largest DEC
8-bit 0xFF 255
16-bit 0xFFFF 65536
32-bit 0xFFFF_FFFF 4294967295
64-bit oxFFFF_FFFF_FFFF_FFFF 18446744073709551615

Signed Integers (Two’s Complement)

Range:$[2^{n-1}, 2^{n-1} -1]$

Table:

Bits Largest HEX Largest DEC Smallest HEX Smallest DEC
8-bit 0x7F 127 0x80 -128
16-bit 0x7FFF 32767 0x8000 -32768
32-bit 0x7FFF_FFFF 2147483647 0x8000_0000 -2147483648
64-bit 0x7FFF_FFFF_FFFF_FFFF 9223372036854775807 0x8000_0000_0000_0000 -9223372036854775808

Data Transfer Instructions

🤓☝️ The GIST Moving stuff (data and addresses) around in Assembly. Think of these like assignment operators and dereferences in C.

MOV

  • Move data from src to dst (dst $\leftarrow$ src).
  • Syntax: MOV dst, src.
    • dst (destination): can be a reg register, or mem memory.
    • src (source): can be a reg register, mem memory, or imm immediate value (literal values).
  • Flags: None.

Special Cases: If dst is 64-bits and src is an imm, then up to sign-extended 32-bit only.

LEA

  • Move address from src to dst (dst $\leftarrow$ &src).
  • Syntax: LEA dst, src.
    • dst (destination): only 16 to 64-bit reg registers.
    • src (source): only mem memory.
  • Flags: None.

NOP

  • Literally do nothing (no operation).
  • Syntax: NOP
  • Flags: None.

Control Transfer Intstructions

🤓☝️ The GIST Controls the flow of your program. Similar to if, else, while, etc. in high-level languages.

Essentially, what allows our code to branch.

CMP

  • Compare the values of two things (A $=$ B).
  • Syntax: CMP srcA, srcB.
    • Treated as srcA - srcB (it’s a subtraction!).
      • If srcA == srcB, then srcA - srcB == 0.
    • srcA: reg register or mem memory.
    • srcB: reg register, mem memory, or imm immediate value from 8 to 32-bits.
  • Flags: All status flags.

JMP

  • Jump to a specific section, akin to go to.
  • Syntax: JMP <label>.
    • <label> specifies “where” we jump.
  • Flags: None.

JCC (Jump with Condition Code)

  • If statement but more complicated (thanks Intel).
  • Requires a CMP call since the JCC will use the result of the CMP.
  • General Syntax: J<CC> <label>.
    • <CC> is the condition code.
    • <label> specifies “where” we jump.
  • Flags: None.

Signed Condition Codes

Condition Code Meaning Jump if (after CMP srcA, srcB)
JE / JZ Jump if equal / zero ZF = 1
JNE / JNZ Jump if not equal / not zero ZF = 0
JL / JNGE Jump if less (signed) SF ≠ OF
JLE / JNG Jump if less or equal (signed) ZF = 1 or SF ≠ OF
JG / JNLE Jump if greater (signed) ZF = 0 and SF = OF
JGE / JNL Jump if greater or equal (signed) SF = OF

Flags:

  • ZF: Zero Flag; if the result of the last operation is 0.
  • SF: Sign Flag; sign of the result of the last operation.
  • OF: Overflow Flag; if overflow occured in the last operation.

Unsigned Condition Codes

Condition Code Meaning Jump if (after CMP srcA, srcB)
JE / JZ Jump if equal / zero ZF = 1
JNE / JNZ Jump if not equal / not zero ZF = 0
JB / JNAE Jump if below (unsigned) CF = 1
JBE / JNA Jump if below or equal (unsigned) CF = 1 or ZF = 1
JA / JNBE Jump if above (unsigned) CF = 0 and ZF = 0
JAE / JNB Jump if above or equal (unsigned) CF = 0

Flags:

  • ZF: Zero Flag; if the result of the last operation is 0.
  • CF: Carry Flag; set if there was an unsigned borrow in subtraction (that is, srcA < srcB).

LOOP

  • Loop a block of code a specified number of times.
  • Syntax: LOOP <label>
    • Decrements RCX (or CX, ECX) by 1.
    • Jumps to <label> if RCX ≠ 0.
  • Flags: None (RCX is updated automatically).

JCXZ / JECXZ

  • Jump if CX / ECX is zero.
  • Syntax:
    • JCXZ <label> (16-bit counter)
    • JECXZ <label> (32-bit counter)
    • Jumps to <label> if CX/ECX is 0.
  • Flags: None.

Stack Control Instructions

PUSH

  • Push a value onto the stack.
  • Syntax: PUSH src
    • src can be a register, memory, or immediate value.
    • Decrements RSP by the operand size (8 bytes for 64-bit) and stores the value at [RSP].
  • Flags: None.

POP

  • Pop a value from the stack.
  • Syntax: POP dst
    • Loads the value at [RSP] into dst and increments RSP by operand size.
    • dst can be a register or memory location.
  • Flags: None.

Procedure Control Instructions

CALL

  • Call a subroutine.
  • Syntax: CALL <label>
    • Pushes the return address (next instruction after CALL) onto the stack.
    • Jumps to <label> (subroutine entry point).
  • Flags: None.

RET

  • Return from a subroutine.
  • Syntax: RET
    • Pops the return address from the stack into RIP and continues execution there.
  • Optional form: RET <imm> to clean up the stack for parameters.
  • Flags: None.