x86

x86 is a backwards compatible family of little-endian, complex instruction set architectures (ISA) introduced in 1978 by Intel[1]. The iterations of the ISA can be broadly classified by integer width:

  • 16-bit x86, also referred to as x86_16 or IA-16 (introduced with the Intel 8086 in 1978)

  • 32-bit x86, also referred to as x86_32 or IA-32 (introduced with the Intel 386 in 1985)

  • 64-bit x86 (not to be confused with IA-64), also referred to as x86_64, AMD64 or x64. It is also referred to as EM64T, IA-32e or Intel64 by Intel.

1. History

The first iteration of the x86 architecture was introduced in 1978 with the 8086. The 8086 was a 16-bit CPU, with 16-bit registers, a 16-bit data bus and a 20-bit address bus. Thus it was able to address one megabyte of RAM. Slightly later, the 8088 CPU was introduced, which was internally identical to the 8086, but had a 8-bit data bus. The 8088 was used by the original IBM PC, introduced in 1981, which was the predecessor of all modern PCs. Thus, the x86 architecture became the dominant architecture on personal computers.

In 1982, Intel introduced the 186, 188 and 286. The 186 and 188 where similar to the 8086 and 8088 respectively, but where intended for embedded systems, and included peripheral that were not compatible with IBM PCs. The Intel 286, however, was intended for multi-user, multitasking environments. Thus the 286 introduced features for multitasking and memory protection and was able to address up to 16 megabytes of RAM. To preserve compatibility with the 8086, most of the features introduced with the 286 could only be used in a mode called protected mode. The 286 and most subsequent x86 processors start in real mode, which emulates the behavior of a 8086. The 286 started to gain wide adoption with the introduction of the IBM AT in 1984.

In 1985, Intel introduced the 386. This new interation introduced support for 32-bit integers and extended protected mode to introduce, among other things, paging and support for up to four gigabytes of RAM.

In 1989, the Intel 486 was introduced, with new features, such as:

  • An integrated "x87" FPU

  • L1 cache used for increased IPC

  • System management capabilities

To this day, every properly-implemented x86 processor has backwards compatibility, all the way back to the original Intel 8086.

2. Operating modes

x86 has a handful of operating modes, used for backwards compatibility.

2.1. Real mode

Real mode is the operating mode that an x86 processor boots into. It mostly models the original 16-bit 8086 processor, with a few extensions.

While data can be handled 16 bits at a time, segment offset registers offer addressing up to 21 bits, which provides the processor with 1MiB of addressable memory.

Real mode contains no access rings or protection of any kind.

2.2. Protected mode (16-bit)

16-bit protected mode runs with 16-bit data and instructions, but segment offset registers are replaced with segment selector registers, which point to an entry into the 16-bit GDT.

Programs written for real mode may have a handful of compatibility issues with 16-bit protected mode, but instructions are still read in the same format.

16-bit protected mode is rarely used.

2.3. Protected mode (32-bit)

32-bit protected mode reads and addresses with 32-bit values. This is the mode commonly referred to as "protected mode". Protected mode mandates a 32-bit before entry. Protected mode is officially entered when a far jump is performed that sets CS to an offset which points to a code segment in a 32-bit GDT.

32 bits of addressing provide up to 4GiB of addressable virtual memory. However, with PAE paging extensions, the virtual address space can be mapped to 64-bit physical addresses, theoretically allowing up to 16PiB of physical memory to be addressed.

2.4. Compatibility mode (x86-64 only)

Compatibility mode runs during the transition from protected mode to long mode. Compatibility mode runs similarly to protected mode, and is used to allow 64-bit structures to be loaded before entering proper long mode.

2.5. Long mode (x86-64 only)

Long mode handles data up to 64 bits in general purpose registers, with extensions that allow for the handling of up to 512 bits of data at a time. Addressing in long mode is 64-bit, theoretically allowing for up to 16PiB of virtual memory to be directly addressed.

However, on most x86-64 processors, only 48 bits of addressing are actually implemented, with the notable exception of processors that support 5-level paging. These 48-bit addresses must all have the top unsupported bits be set or unset, resulting in two "halves" of the virtual address space. These addresses are referred to as "canonical" addresses.

The name "long mode" refers to the commonplace technical term for a 64-bit integer, a "long".

Due to the unfulfillable amount of virtual memory, PAE paging is mandated in long mode. This allows for contiguous mapping of physical RAM, with memory-mapped IO out of physical RAM space. This also allows x86-64 operating systems to implement "swap memory", a process where virtual addresses point to data not in physical RAM, but rather stored on disk.

3. Extensions

x86 processors have a plethora of extensions that expand on standard behavior. The most notable, x86-64, implements 64-bit addressing and long mode.

This section only contains a handful of extensions, there are too many to list at once.

3.1. x86-64

The x86-64 extension is quite expansive, implementing the 64-bit operating mode and 64-bit addressing. It is nearly impossible to find a working computer today that does not support x86-64.

3.2. PAE/NX

PAE/NX implements 4-level paging, and adds a handful of properties to pages to implement extensive memory protection, including NX, a flag to disable execution on a particular page.

Most operational computers today support PAE/NX.

3.3. x87

x87 is a floating-point calculation extension. While technically an extension, it is supported on most x86 processors.

3.4. SSE

SSE is a 128-bit data extension. It adds 8-16 128-bit general purpose XMM registers, and instructions to perform SIMD vector math.

SSE has several versions. x86-64 processors are mandated to support at least SSE2.

3.5. AVX

AVX is a 256-bit data extension. It performs a purpose similar to SSE, and implements a handful of 256-bit YMM registers.

AVX was released alongside the Sandy Bridge microarchitecture in 2011. A not-insignificant number of operational computers today do not support AVX.

3.5.1. AVX-512

AVX-512 is not a single extension, but rather a family of extensions. It is similar to AVX, but implements a handful of 512-bit ZMM registers.

AVX-512 is quite new, with consumer processors supporting AVX-512 being released in 2018.[2] It is yet to become widely supported.