x86 is a 32-bit CISC-style instruction set architecture, mainly for Intel and AMD CPUs. The 64-bit version, x86-64 (or amd64), extends on x86 by supporting much more virtual and physical memory.

Why do x86 CPUs take so much power? Turns out there’s a RISC emulation layer within the CPU to support pipelining. CISC instructions are decoded into RISC-style instructions.

Features

x86 has a huge amount of architectural features that other languages don’t have, because it’s effectively been in continuous development from an 8-bit architecture to 64-bit since the 70s.

  • SIMD instructions were added in the “Multimedia eXtension” update around ~1997.
    • SSE (Streaming SIMD Extension) extends SIMD to single-precision floating-point numbers.
    • SSE2 adds support for double-precision floats.

Instructions

Instructions are not fixed-length. They can vary between 1-18 bytes.

Control flow:

  • callf: subroutine call. This places the return address on a stack in memory.

Registers

The x86-64 ABI (called System V) specifies a calling convention and stack alignment. The calling convention is register-based and is given by:

  • The first 6 integer/pointer parameters are stored in: rdi, rsi, rdx, rcx, r8, and r9, respectively. Any more parameters must be put on the stack.
  • Floating-point inputs passed in xmm0 to xmm7.
  • Integer/pointer return values are put in rax and float returns are put in xmm0.
  • Registers rax, rcx, rdx, rsi, rdi, r8 to r11 are caller-saved.
  • Registers rbx, rbp, r12 to r15 are callee-saved.

The ABI also specifies a 16-byte stack alignment boundary. Most operating systems (Linux, macOS, Windows) use this ABI.