The generic term x86 refers to the most commercially successful instruction set architecture in the history of personal computing. It derived from the model numbers, ending in "86", of the first few processor generations backward compatible with the original Intel 8086. Since then, many additions and extensions have been added to the x86 instruction set, almost consistently with full backwards compatibility. The architecture has been implemented in processors from Intel, Cyrix, AMD, VIA, and many others.
As the x86 term became common after the introduction of the 80386, it usually implies a binary compatibility with the 32-bit instruction set of the 80386. This may sometimes be emphasized as x86-32 to distinguish it either from the original 16-bit x86-16 or from the newer 64-bit x86-64 (also called x64). Although most x86 processors used in new personal computers and servers have 64-bit capabilities, to avoid compatibility problems with older computers or systems, the term x86-64 is often used to denote 64-bit software, with the term x86 implying only 32-bit.
Today, the x86 architecture is ubiquitous among desktop and notebook computers, as well as a growing majority among servers and workstations. A large amount of software supports the platform, including OSes such as MS-DOS, Windows, Linux, BSD, Solaris, and Mac OS X. The architecture is relatively uncommon in embedded systems however, and low-cost niches such as appliances and toys lack any significant x86 presence. Simpler 16-bit x86 chips are more common here, but AMD's Geode CPU and the new Intel Atom are examples of 32-bit designs used in this segment.
Contrary to some popular belief, x86 is not synonymous with IBM PC compatibility as this also implies a multitude of other hardware, albeit with some of it standardized. For instance, the original Xbox was designed around an x86 processor but security restrictions led to software requirements making it incapable of simply running standard code designed for other IBM PC compatible systems. Also, the GRID Compass laptop (one of the first on the market), and many others, used x86 chips before the IBM PC compatible market even started.
| Generation | First introduced | Prominent Consumer CPU brands | linear / physical address space | Notable (new) features |
|---|---|---|---|---|
| 1 (IA-16) | 1978 | Intel 8086, Intel 8088 | 16-bit / 20-bit (segmented) | first x86 microprocessors |
| 2 | 1982 | Intel 80186, Intel 80188, NEC V20 | hardware for fast address calculations, fast mul/div etc | |
| Intel 80286 | 16-bit (30-bit virtual) / 24-bit (segmented) | MMU, for protected mode and a larger address space | ||
| 3 (IA-32) | 1985 | Intel386, AMD Am386 | 32-bit (46-bit virtual) / 32-bit | 32-bit instruction set, MMU with paging |
| 4 | 1989 | Intel486 | risc-like pipelining, integrated FPU, on-chip cache | |
| 5 | 1993 | Pentium, Pentium MMX | superscalar, 64-bit databus, faster FPU, MMX | |
| 5/6 | 1996 | Cyrix 6x86, Cyrix MII | register renaming, speculative execution | |
| 6 | 1995 | Pentium Pro, AMD K5, Nx586 (1994) | as above / 36-bit physical (PAE) | μ-op translation, PAE (not K5, Nx586), integrated L2 cache (not K5, Nx586) |
| 1997 | AMD K6/-2/3, Pentium II/III | L3-cache support, 3D Now, SSE | ||
| 7 | 1999 | Athlon, Athlon XP | superscalar FPU, wide design (up to three x86 instr./clock) | |
| 2000 | Pentium 4 | deeply pipelined, high frequency, SSE2, hyper-threading | ||
| 6-M/7-M | 2003 | Pentium M, Intel Core | optimized for low power | |
| 8 (x86-64) | Athlon 64, Opteron | 64-bit / 40-bit physical in first impl. | x86-64 instruction set, on-die memory controller, hypertransport | |
| 2004 | Pentium 4 Prescott | very deeply pipelined, very high frequency, SSE3 | ||
| 9 | 2006 | Intel Core 2 | low power, multi-core, lower clock frequency, SSE4 (Penryn) | |
| 10 | 2007 | AMD Phenom, Intel Core i7 | as above / 44-bit physical for Beckton Core i7 | monolithic quad-core, 128 bit FPUs, SSE4a, HyperTransport 3 or QuickPath, native memory controller, on-die L3 cache, modular design |
| ? | 2008 | Intel Atom | In-order but highly pipelined, very-low-power | |
| 11 | 2010 | Intel Sandy Bridge, AMD Bulldozer | SSE5/AVX, highly modular design |
Following the fully pipelined i486, Intel introduced the Pentium brand name (which, unlike numbers, could be trademarked) for their new line of superscalar x86 designs. With the x86 naming scheme now legally cleared, IBM partnered with Cyrix to produce the 5x86 and then the very efficient 6x86 (M1) and 6x86MX (MII) lines of Cyrix designs, which were the first x86 chips implementing register renaming to enable speculative execution. AMD meanwhile designed and manufactured the advanced but delayed 5k86 (K5), which, internally, was heavily based on AMD's earlier 29K RISC design; similar to NexGen's Nx586, it used a strategy where dedicated pipeline stages decode x86 instructions into uniform and easily handled micro-operations, a method that has remained the basis for most (not all) x86 designs to this day.
Some early versions of these chips had heat dissipation problems. The 6x86 was also affected by a few minor compatibility issues, the Nx586 lacked an FPU and (the then crucial) pin-compatibility, while the K5 had somewhat disappointing performance when it was (eventually) launched. A low customer awareness of alternatives to the Pentium line further contributed to these designs being comparatively unsuccessful, despite the fact that the K5 had very good Pentium compatibility and the 6x86 was significantly faster than the Pentium on integer code. AMD later managed to establish itself as a serious contender with the K6 line of processors, which gave way to the highly successful Athlon and Opteron. There were also other contenders, such as Centaur Technology, (IDT), Rise Technology, and Transmeta. VIA Technologies' energy efficient C3 and C7 processors, which were designed by Centaur, have been sold for many years, and Centaur newest design, the VIA Nano, is their first processor with superscalar and speculative execution. It was, perhaps interestingly, introduced at about the same time as Intels first "in-order" processor since the original Pentium, the Intel Atom.
To conserve opcode space, most register-addresses are three bits, and at most one operand can be in memory (some highly orthogonal "CISC" designs, such as the PDP-11, may use two memory operands), but this memory operand may also be the destination, while the other operand, the source, can be either register or immediate. This contributes, among other factors, to a code footprint that rivals eight-bit machines and enables efficient use of instruction cache memory. The relatively small number of general registers (also inherited from 8085) has made register-relative addressing (using small immediate offsets) an important method of accessing operands, especially on the stack. Much work has therefore been invested in making such accesses as fast as register accesses, i.e. a one cycle instruction throughput in most circumstances.
When introduced, this approach was sometimes referred to as a "RISC core" or as "RISC translation", partly for marketing reasons, but also because these micro-operations share some properties with certain types of RISC instructions. However, also traditional microcode (used since the 1950s) inherently share many of the same properties! The new approach differs mainly in that the translation to micro-operations now occurs asynchronously. Not having to synchronize the execution units with the decode steps opens up for more analysis of the (buffered) code stream, and therefore permits detection of operations that can be performed in parallel and thus feed more than one execution unit at once.
The latest processors also do the opposite when appropriate; they combine certain x86 sequences (such as a compare followed by a conditional jump) into a more complex μop which fits the execution model better and thus can be executed faster or with less machine resources involved.
Another way to try to improve performance is to cache the decoded micro-operations, so the processor can directly access the decoded micro-operations from a special cache, instead of decoding them again. The Execution Trace Cache found in Intel's NetBurst Microarchitecture (Pentium 4) is so far the only widespread example of this technique.
Transmeta use a completely different method in their x86 compatible CPUs. They use just-in-time translation to convert x86 instructions to the CPU's native instructions. Transmeta argues that their approach allows for more power efficient designs since the CPU can forgo the complicated decode step of more traditional x86 implementations.
Data and/or code could be managed within "near" 16-bit segments within this 1 MB address space, or a compiler could operate in a "far" mode using 32-bit segment:offset pairs reaching (only) 1 MB. While that would also prove to be quite limiting by the mid-1980s, it was working for the emerging PC market, and made it very simple to translate software from the older 8080, 8085, and Z80 to the newer processor. In 1985, the 16 bit segment addressing model was effectively factored out by the introduction of 32-bit offset registers, in the 386 design.
In real mode, segmentation is achieved by shifting the segment address left by 4 bits and adding an offset in order to receive a final 20-bit address. For example, if DS is A000h and SI is 5677h, DS:SI will point at the absolute address DS × 16 + SI = A5677h. Thus the total address space in real mode is 220 bytes, or 1 MB, quite an impressive figure for 1978. All memory addresses consist of both a segment and offset; every type of access (code, data, or stack) has a default segment register associated with it (for data the register is usually DS, for code it is CS, and for stack it is SS). For data accesses, the segment register can be explicitly specified (using a segment override prefix) to use any of the four segment registers.
In this scheme, two different segment/offset pairs can point at a single absolute location. Thus, if DS is A111h and SI is 4567h, DS:SI will point at the same A5677h as above. This scheme makes it impossible to use more than four segments at once. CS and SS are vital for the correct functioning of the program, so that only DS and ES can be used to point to data segments outside the program (or, more precisely, outside the currently-executing segment of the program) or the stack.
In protected mode, a segment register no longer contains the physical address of the beginning of a segment, but contain a "selector" that points to a system-level structure called a segment descriptor. A segment descriptor contains the physical address of the beginning of the segment, the length of the segment, and access permissions to that segment. The offset is checked against the length of the segment, with offsets referring to locations outside the segment causing an exception. Offsets referring to locations inside the segment are combined with the physical address of the beginning of the segment to get the physical address corresponding to that offset.
The segmented nature can make programming and compilers design difficult because the use of near and far pointers affect performance.
Addressing modes for 32-bit code on 32-bit or 64-bit x86 processors can be summarized by this formula:
Addressing modes for 64-bit code on 64-bit x86 processors can be summarized by these formulas:
and
The 8086 had 64 KB of 8-bit (or alternatively 32 K-word of 16-bit) I/O space, and a 64 KB (one segment) stack in memory supported by hardware. Only words (2 bytes) can be pushed to the stack. The stack grows downwards (toward numerically lower addresses), its bottom being pointed by SS:SP. There are 256 interrupts, which can be invoked by both hardware and software. The interrupts can cascade, using the stack to store the return address.
No particular purposes were envisaged for the other 8 registers available only in 64-bit mode.
Some instructions compile and execute more efficiently when using these registers for their designed purpose. For example, using AL as an accumulator and adding an immediate byte value to it produces the efficient add to AL opcode of 04h, whilst using the BL register produces the generic and longer add to register opcode of 80C3h.
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|
| R?X | |||||||
| E?X | |||||||
| ?X | |||||||
| ?H | ?L | ||||||
Segment Registers (C, D, S, E, F, and G)
| 1 | 0 |
|---|---|
| ?S | |
Pointer Registers (S and B)
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|
| R?P | |||||||
| E?P | |||||||
| ?P | |||||||
Index Registers (S and D)
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|
| R?I | |||||||
| E?I | |||||||
| ?I | |||||||
Instruction Pointer Register (I)
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|
| R?P | |||||||
| E?P | |||||||
| ?P | |||||||
x86-64-only General Purpose Registers (R8, R9, R10, R11, R12, R13, R14, R15)
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|
| ? | |||||||
| ?D | |||||||
Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F
0000 31 C0 8E D0 66 BC 00 7C FB 66 B8 C0 07 8E D8 90 1ÀŽÐf¼.|ûf¸À.ŽØ
0010 B4 00 B0 00 CD 10 B0 00 B4 05 CD 10 B5 00 B1 07 ´.°.Í.°.´.Í.µ.±.
0020 B4 01 CD 10 B6 09 B2 09 B7 00 B4 02 CD 10 8C D8 ´.Í.¶.².·.´.Í.ŒØ
0030 8E C0 B4 13 B0 00 B7 00 B3 0F B9 0C 00 B6 09 B2 ŽÀ´.°.·.³.¹..¶.²
0040 09 BD 50 00 CD 10 B7 00 B4 08 CD 10 EB FE CD 19 .½P.Í.·.´.Í.ëþÍ.
0050 68 65 6C 6C 6F 20 77 6F 72 6C 64 21 90 90 90 90 hello world!....
0060 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 ................
0070 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 ................
0080 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 ................
0090 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 ................
00A0 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 ................
00B0 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 ................
00C0 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 ................
00D0 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 ................
00E0 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 ................
00F0 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 ................
0100 41 75 74 68 6F 72 3A 90 90 90 90 90 90 90 90 90 ................
0110 62 6F 6F 74 40 76 65 6E 74 75 72 6F 6E 2E 6F 72 ................
0120 67 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 ................
0130 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 ................
0140 4C 69 6E 6B 73 3A 90 90 90 90 90 90 90 90 90 90 ................
0150 77 77 77 2E 62 6F 6F 74 6C 65 76 65 6C 2E 62 6C ................
0160 6F 67 73 70 6F 74 2E 63 6F 6D 90 90 90 90 90 90 ................
0170 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 ................
0180 77 77 77 2E 76 65 6E 74 75 72 6F 6E 2E 6F 72 67 ................
0190 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 ................
01A0 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 ................
01B0 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 ................
01C0 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 ................
01D0 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 ................
01E0 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 ................
01F0 90 90 90 90 90 90 90 90 90 90 90 90 90 90 55 AA ..............Uª
More Info
Real mode is an operating mode of 80286 and later x86-compatible CPUs. Real mode is characterized by a 20 bit segmented memory address space (meaning that only 1 MB of memory can be addressed), direct software access to BIOS routines and peripheral hardware, and no concept of memory protection or multitasking at the hardware level. All x86 CPUs in the 80286 series and later start up in real mode at power-on; 80186 CPUs and earlier had only one operational mode, which is equivalent to real mode in later chips.
In order to use more than 64 KB of memory, the segment registers must be used. This created great complications for C compiler implementors who introduced odd pointer modes such as "near", "far" and "huge" to leverage the implicit nature of segmented architecture to different degrees, with some pointers containing 16-bit offsets within implied segments and other pointers containing segment addresses and offsets within segments.
In addition to real mode, the Intel 80286 supports protected mode, expanding addressable physical memory to 16 MB and addressable virtual memory to 1 GB, and providing protected memory, which prevents programs from corrupting one another. This is done by using the segment registers only for storing an index to a segment table. There were two such tables, the Global Descriptor Table (GDT) and the Local Descriptor Table (LDT), each holding up to 8192 segment descriptors, each segment giving access to 64 KB of memory. The segment table provided a 24-bit base address, which can be added to the desired offset to create an absolute address. Each segment can be assigned one of four ring levels used for hardware-based computer security.
The Intel 80386 introduced support in protected mode for paging, a mechanism making it possible to use virtual memory.
Paging and segmented memory access are required for modern multitasking operating systems. Linux, 386BSD and Windows NT were developed for the 386 because it was the first Intel architecture CPU to support paging and 32-bit segment offsets. The 386 architecture became the basis of all further development in the x86 series. The success of Windows 3.0, the first widely accepted version of Microsoft Windows, was largely due to its ability to take advantage of 386 features, even though it was used mainly to run multiple sessions rather than to take advantage of the native 32-bit instruction set.
x86 processors that support protected mode boot into real mode for backward compatibility with the older 8086 class of processors. Upon power-on (aka booting), the processor initiates itself into Real mode, and then it begins loading programs automatically into RAM from ROM and disk. A program inserted somewhere along the boot sequence may be used to put the processor into the Protected mode. The instruction set in protected mode is backward compatible with the one used in real mode.
AMD, who would traditionally follow the lead of Intel, took the initiative of extending the 32-bit x86 architecture to 64-bit, initially calling it x86-64, later renaming it AMD64. The Opteron, Athlon 64, Turion 64, and later Sempron families of processors use this architecture. The success of the AMD64 line of processors coupled with the lukewarm reception of the IA-64 architecture forced Intel to release their own x86-64 instruction set. Intel had previously developed an x86-64 instruction set but opted not to enable it in hopes that AMD would not make it to market with theirs before Itanium's new IA-64 instruction set was widely adopted. They branded their extensions EM64T architecture, and later re-branded it Intel 64.
In its literature and product version names, Microsoft and Sun refer to AMD64/Intel 64 collectively as x64 in the Windows and Solaris operating systems respectively. Linux distributions refer to it either as "x86-64", its variant "x86_64", or "amd64". BSD systems use "amd64" while Mac OS X uses "x86_64".
Long mode is mostly an extension of the 32-bit instruction set, but unlike the 16–to–32-bit transition, many instructions were dropped in the 64 bit mode. This does not affect actual binary backward compatibility (which would execute legacy code in other modes that retain support for those instructions), but it changes the way assembler and compilers for new code have to work.
This was the first time that a major upgrade of the x86 architecture was initiated and originated by a manufacturer other than Intel. It was also the first time that Intel accepted technology of this nature from an outside source.
These registers are not accessible directly, but are accessible like a LIFO stack. The register numbers are not fixed, but are relative to the top of the stack; ST(0) is the top of the stack, ST(1) is the next register below the top of the stack, ST(2) is two below the top of the stack, etc. That means that data is always pushed down from the top of the stack, and operations are always done against the top of the stack. Register access had to be done in the stack order, not randomly.
MMX is a SIMD instruction set designed by Intel, introduced in 1997 for Pentium MMX microprocessors. It developed out of a similar unit first used on the Intel i860. It first appeared in the Pentium MMX. It is supported on most subsequent IA-32 processors by Intel and other vendors. MMX is typically used for video applications.
MMX added 8 new "registers" to the architecture, known as MM0 through MM7 (henceforth referred to as MMn). In reality, these new "registers" were just aliases for the existing x87 FPU stack registers. Hence, anything that was done to the floating point stack would also affect the MMX registers. Unlike the FP stack, these MMn registers were fixed, not relative, and therefore they were randomly accessible. The instruction set did not adopt the stack-like semantics so that existing operating systems could still correctly save and restore the register state when multitasking without modifications.
Each of the MMn registers are 64-bit integers. However, one of the main concepts of the MMX instruction set is the concept of packed data types, which means instead of using the whole register for a single 64-bit integer (quadword); two 32-bit integers (doubleword), four 16-bit integers (word) or eight 8-bit integers (byte) may be used. Also because the MMX's 64-bit MMn registers are aliased to the FPU stack, and each of the stack registers are 80-bit wide, the upper 16-bits of the stack registers go unused in MMX, and these bits are set to all ones, which makes it look like NaN's or infinities in the floating point view. This makes it easier to tell whether you are working on a floating point data or MMX data.
In 1997 AMD introduced 3DNow! The introduction of this technology coincided with the rise of 3D entertainment applications and was designed to improve the CPU's vector processing performance of graphic-intensive applications. 3D video game developers and 3D graphics hardware vendors use 3DNow! to enhance their performance on AMD's K6 and Athlon series of processors.
3DNow! was designed to be the natural evolution of MMX from integers to floating point. As such, it uses the exact same register naming convention as MMX, that is MM0 through MM7. The only difference is that instead of packing byte to quadword integers into these registers, one would pack single precision floating points into these registers. The advantage of aliasing registers with the FPU registers is that the same instruction and data structures used to save the state of the FPU registers can also be used to save 3DNow! register states. Thus no special modifications are required to be made to operating systems which would otherwise not know about.
In 1999, Intel introduced the Streaming SIMD Extensions (SSE) instruction set, following in 2000 with SSE2. The first addition made MMX almost obsolete and the second allowed the instructions to be realistically targeted by conventional compilers. Introduced in 2004 along with the Prescott revision of the Pentium 4 processor, SSE3 added specific memory and thread-handling instructions to boost the performance of Intel's HyperThreading technology. AMD licensed the SSE3 instruction set and implemented most of the SSE3 instructions for its revision E and later Athlon 64 processors. The Athlon 64 does not support HyperThreading and lacks those SSE3 instructions used only for HyperThreading.
SSE discarded all legacy connections to the FPU stack. This also meant that this instruction set discarded all legacy connections to previous generations of SIMD instruction sets like MMX. But it freed the designers up, allowing them to use larger registers, not limited by the size of the FPU registers. The designers created eight 128-bit registers, named XMM0 through XMM7. (Note: in AMD64, the number of SSE XMM registers has been increased from 8 to 16.) However, the downside was that operating systems had to have an awareness of this new set of instructions in order to be able to save their register states. So Intel created a slightly modified version of Protected mode, called Enhanced mode which enables the usage of SSE instructions, whereas they stay disabled in regular Protected mode. An OS that is aware of SSE will activate Enhanced mode, whereas an unaware OS will only enter into traditional Protected mode.
SSE is a SIMD instruction set that works only on floating point values, like 3DNow!. However, unlike 3DNow! it severs all legacy connection to the FPU stack. Because it has larger registers than 3DNow!, SSE can pack twice the number of single precision floats into its registers. The original SSE was limited to only single-precision numbers, like 3DNow!. The SSE2 introduced the capability to pack double precision numbers too, which 3DNow! had no possibility of doing since a double precision number is 64-bit in size which would be the full size of a single 3DNow! MMn register. At 128-bit, the SSE XMMn registers could pack two double precision floats into one register. Thus SSE2 is much more suitable for scientific calculations than either SSE1 or 3DNow!, which were limited to only single precision. SSE3 does not introduce any additional registers.
Intel and AMD have introduced x86 processors with hardware-based virtualization extensions that overcome the classical virtualization limitations of the x86 architecture. These extensions are known as Intel VT (IVT or simply VT) that was code named "Vanderpool," and AMD-V that was code named "Pacifica." Although most modern x86 server-based and many modern x86 desktop-based processors include these extensions, the technology is generally considered immature at this point with most software-based virtualization outperforming these extensions. This is expected to change as the technology matures.
*