x86

中央處理器指令集架構

x86泛指一系列基于Intel 8086且向后兼容的中央处理器指令集架构。最早的8086处理器于1978年由Intel推出,为16位微处理器。

x86
推出年份1978年(16位元)、1985年(32位元)、2003年(64位元)
设计公司IntelAMD
是否开放架构?部分
字长/暂存器资料宽度32、64、128
位元组序小端序
指令集架构设计策略CISC

该系列较早期的处理器名称是以数字来表示80x86。由于以“86”作为结尾,包括Intel 8086801868028680386以及80486,因此其架构被称为“x86”。由于数字并不能作为注册商标,因此Intel及其竞争者均在新一代处理器使用可注册的名称,如Pentium,来描述x86架构下的处理器产品。现时英特尔将其称为IA-32,全名为“Intel Architecture, 32-bit”,一般情形下指代32位元的架构。

历史

x86架构于1978年推出的Intel 8086中央处理器中首度出现,它是从Intel 8008处理器中发展而来的,而8008则是发展自Intel 4004的。8086在三年后为IBM PC所选用,之后x86便成为了个人电脑的标准平台,成为了历来最成功的CPU架构。

其他公司也有制造x86架构的处理器,计有Cyrix(现为威盛电子所收购)、NEC集团IBMIDT以及Transmeta。Intel以外最成功的制造商为AMD,其早先产品Athlon系列处理器的市场份额仅次于Intel Pentium

8086是16位元处理器;直到1985年32位元的80386的开发,这个架构都维持是16位元。接著一系列的处理器表示了32位元架构的细微改进,推出了数种的扩充,直到2003年AMD对于这个架构发展了64位元的扩充,并命名为AMD64。后来英特尔也推出了与之兼容的处理器,并命名为Intel 64。两者一般被统称为x86-64x64,开创了x86的64位时代。

值得注意的是英特尔早在1990年代就与惠普合作提出了一种用在安腾系列处理器中的独立的64位架构,这种架构被称为IA-64。IA-64是一种崭新的系统,和x86架构完全没有相似性;不应该把它与x86-64x64弄混。

CPU纪元朝代 面市时间
(西元 年)
卓越的CPU型号 记忆体位置找寻空间 引入功能及注释
序列 模拟 实体
x86 第一代 1978 Intel 8086, Intel 8088(1979) 16位元 20位元 16位元 架构, IBM PC (8088), IBM PC/XT英语IBM PC/XT (8088)
1982 Intel 80186, Intel 80188
NEC V20英语NEC V20/V30(1983)
8086-2架构, 嵌入技术(80186/80188)
第二代 Intel 80286及其克隆产品 30位元 24位元 保护模式(16位元), IBM PC XT 286英语IBM PC/XT#IBM XT 286, IBM PC AT
第三代 (IA-32)架构 1985 Intel 80386, AMD Am386英语AMD Am386 (1991) 32位元 46位元 32位元 32位元 架构(保护模式), 分页技术,模拟8086模式, IBM PS/2
第四代 (管线、快取记忆体) 1989 Intel 80486
Cyrix Cx486S/DLC(1992)
AMD Am486英语AMD Am486(1993)/AMD Am5x86英语AMD Am5x86(1995)
管线, 置晶x87英语x87 浮点运算器 (486DX), 置晶CPU快取记忆体
第五代
(超纯量)
1993 Intel Pentium, Pentium MMX英语P5_(microarchitecture)#MMX(1996) 超纯量, 64位元 位址汇流排, 更快的浮点运算器, MMX (Pentium MMX), 进阶程式化插断控制器英语Advanced Programmable Interrupt Controller, 对等多元处理
1994 NexGen Nx586
AMD 5k86/K5 (1996)
分合式微架构(微作业指令转换)
1995 Cyrix Cx5x86
Cyrix 6x86/MX(1997)/MII英语Cyrix_6x86#6x86MX_/_MII(1998)
脱序超纯量执行引擎
第六代
(实记忆体位置扩充, 微作业指令转换)
1995 Intel Pentium Pro 36位元 (PAE) 微作业指令转换, 待情形检索指令, 脱序超纯量执行引擎, 推理型执行引擎, 三路x86超纯量管线, 超纯量浮点运算器, 实记忆体位置扩充, 置片二次元快取
1997 Intel Pentium II, Pentium III (1999)
Celeron(1998), Xeon(1998)
置体(Pentium II)或置晶(Celeron)二次元快取, SSE (Pentium III), SLOT 1, Socket 370 or SLOT 2 (Xeon)
1997 AMD K6/K6-2(1998)/K6-III(1999) 32位元 3DNow!, 三次元快取系统 (K6-III)
增强型平台 1999 AMD Athlon, Athlon XP/MP(2001)
Duron(2000), Sempron(2004)
36位元 MMX+, 3DNow!+, DDR技术引入前端汇流排, Slot A or Socket A
2000 Transmeta Crusoe英语Transmeta Crusoe 32位元 “变形”CMS技术下的x86平台处理器, VLIW-128核心, 置晶记忆体控制器, 置晶PCI桥控制器
Intel Pentium 4 36位元 SSE2, 超执行绪 (Northwood), NetBurst微架构, QDR技术引入前端汇流排, 执行跟踪快取, Socket 478
2003 Intel Pentium M
Intel Core (2006), Pentium Dual-Core (2007)
微作业指令融合, NX位元 (Dothan)
Transmeta Efficeon英语Transmeta Efficeon CMS 6.0.4, VLIW-256, NX位元, HT汇流排
IA-64 64位元过渡时代
1999 ~ 2005
2001 Intel Itanium (2001 ~ 2017) 52位元 64位元 EPIC架构, 128位元VLIW指令捆绑, 置晶x86硬体支援x86作业系统和程式(早期版本),软体IA-32 EL模拟x86程式(Itanium 2), Itanium 通用暂存器被映射成x86暂存器
x64 64位元拓展时代
从2001起
x64是x86架构的64位元拓展,在它的遗留模式中原封了完整不变的x86架构。x64处理器的真正架构置于64位元模式中,它没有分段式的定位记忆体能力,因此它仅拥有架构许诺的64位元序列记忆体位置,现时情况仅有48位元被实现;与这个64位元模式共生的是用来支援大部分32位元x86程式的相容模式
2003 Athlon 64/FX/X2(2005), Opteron
Sempron(2004)/X2(2008)
Turion 64(2005)/X2(2006)
40位元 AMD64 (排除早先一些32位元Sempron处理器), 置晶记忆体控制器, HT汇流排, 置晶双核心(X2), AMD-V (Athlon 64 Orleans), Socket 754/939/940 or AM2
2004 Pentium 4 (Prescott)
Celeron D, Pentium D (2005)
36位元 EM64T (仅在特定型号的Pentium 4和Celeron D开启), SSE3, 第二代NetBurst管线, 双核心(置晶: Pentium D 8xx; 置片: Pentium D 9xx), Intel VT(Pentium 4 6x2), socket LGA 775
2006 Intel Core 2
Pentium Dual-Core (2007)
Celeron Dual-Core (2008)
Intel 64 (<<== EM64T), SSSE3(65奈米), 宽域脱序超纯量执行引擎, 微作业指令融合, 巨集融合, 置片四核心(Core 2 Quad), 智慧型分享二次元快取
2007 AMD Phenom/II(2008)
Athlon II(2009), Turion II(2009)
48位元 Monolithic quad-core(X4)/triple-core(X3), SSE4a, Rapid Virtualization Indexing (RVI), HT汇流排 3, AM2+ or AM3
2008 Intel Core 2 (45奈米) 36位元 SSE4.1
Intel Atom 小笔电或低功耗智慧型装置的处理器, P54C核心的重用
Intel Core i7
Core i5 (2009), Core i3 (2010)
QuickPath, 置片绘图及记忆体汇流排 (Clarkdale英语Clarkdale (microprocessor)), SSE4.2, 扩展页表 (EPT), LGA 1366 (Nehalem) or LGA 1156 socket
VIA Nano 基于硬体的加密元件; 智慧适应型电源管理
2010 AMD FX 48位元 八核心, CMT(丛集多执行绪), 乘积累加运算, OpenCL, AM3+
2011 AMD APU A and E Series (Llano) 40位元 置晶GPGPU, PCI Express 2.0, Socket FM1
AMD APU C, E and Z Series (Bobcat) 36位元 低功耗智慧型装置APU
Intel Core i3, Core i5 and Core i7
(Sandy Bridge/Ivy Bridge)
内部环形连接, LGA 1155 socket.
2012 AMD APU A Series (Bulldozer, Trinity and later) 48位元 AVX, Bulldozer based APU, Socket FM2 or Socket FM2+
Intel Xeon Phi (Knights Corner) 48位元 辅助处理器作业系统支撑的PCI-E界面卡形式的XEON系统的辅助处理器, 多异核心晶片, 顺序P54C, 超宽VPU (512位元 SSE), LRBni 指令(8× 64位元)
2013 AMD Jaguar
(Athlon, Sempron)
48位元 SoC, 适用于电子游乐器和低功耗智慧型装置的处理器
Intel Silvermont英语Silvermont
(Atom, Celeron, Pentium)
36位元 SoC, 低或极低功耗智慧型装置的处理器
Intel Core i3, Core i5 and Core i7 (Haswell/Broadwell) 39位元 AVX2, FMA3, TSX, BMI1, and BMI2英语Bit Manipulation Instruction Sets instructions, LGA 1150 socket
2015 Intel Broadwell-U
(Intel Core i3, Core i5, Core i7, Core M, Pentium, Celeron)
SoC, 置片Broadwell-U PCH-LP (多晶元模组)
2015/2016 Intel Skylake/Kaby Lake/Cannonlake英语Cannon Lake (microarchitecture)
(Intel Core i3, Core i5, Core i7)
46位元 AVX3
2016 Intel Xeon Phi (Knights Landing) 48位元 孤立启动型Xeon系统的加速器, 基于Airmont (Atom)核心技术
2016 AMD Bristol Ridge
(AMD (Pro) A6/A8/A10/A12)
48位元 置晶FCH, SoC, AM4 socket
2017 AMD Ryzen Series/AMD Epyc Series AMD的多执行绪技术, LGA (4094, Epyc), 置片多晶元, Epyc将取代Opteron产品线
软体模拟时代
ARM64
2017 Windows 10 on ARM64 Microsoft与Qualcomm的合作结晶将Windows 10带入至基于ARM64的Qualcomm平台,并针对32位元x86程式提供CHPE模拟器有效支援,从版本1709 (16299.15)起
CPU纪元朝代 面市时间 卓越的CPU型号 实记忆体位置找寻空间 引入功能及注释

设计

x86架构是重要地可变指令长度的CISC(复杂指令集电脑,Complex Instruction Set Computer)。字组(word, 4位元组)长度的记忆体存取允许不对齐记忆体位址,字组是以低位字节在前的顺序储存在记忆体中。向后相容性及Intel量产制程经常领先业界一直都是在x86架构的发展背后一股驱动力量(设计的需要决定了这项因素而常常导致批评,尤其是来自对手处理器的拥护者和理论界,他们对于一个被广泛认为是落后设计的架构的持续成功感到不解)。但在较新的微架构中,x86处理器会将常用的x86指令尽全力以硬体线路执行,不常用者则转换为更像RISC的微指令再予执行,从而获得可与RISC比拟的超纯量性能,而仍然保持向后兼容。x86架构的处理器一共有四种执行模式,分别是真實模式保护模式系统管理模式以及虚拟V86模式

在这篇简短的文章中出现的指令和暂存器助忆符号的名称,都在Intel文件中有所指定以及使用在Intel组译器(Assembler)中(和相容的,比如微软MASMBorland的TASM、CAD-UL的as386等等)。一个以Intel语法指定的指令"mov al, 30h"与AT&T语法的"movb $0x30, %al"相当,都是会被转译为两个字节的机器码"B0 30"(十六进制)。你可以发现在这段程式中的"mov"或"al",都是原来的Intel助忆符号。如果我们想要的话,我们可以写一个组译器由程式码move immediate byte hexadecimally encoded 30 into low half of the first register(移动立即值位元十六进制编码30到第一个暂存器的低半部位),来产生相同的机器码。然而,传统上组译器(Assembler)一直使用Intel的助忆符号。

x86组合语言会在x86组合语言英语x86 assembly language文章中有更详细的讨论。

运作模式

真实模式

在真实模式下,记忆体的存取是被区段开来。为了得到最后20位元的记忆体位址,要将区段的位址往左移动4位元,并且加上偏移的位址。因此,真实模式下总共可以定址的空间是220位元组,或者是1MB,于1979年是相当让人印象深刻的象征。在真实模式下有两种定址模式:near和far。在far模式,区段跟偏移都需要被指定;在near模式,只需要偏移模式被指定,而记忆体区段是由适当的区段暂存器获得。以资料而言是使用DS暂存器,程式码是CS暂存器,堆叠是SS暂存器。举个例子,如果DS是A000h且SI是5677h,DS:SI会指向记忆体的绝对位址DS × 16 + SI = A5677h

在这种架构下,两对不同的区段/偏移可以指向一个相同的绝对位址。因此如果DS是A111h且SI是4567h,DS:SI会指向跟上一段相同的A5677h。除了异值同址重复性之外,这种架构无法同时一次拥有4个以上的区段。此外,CS、DS和SS是为了程式正确功能而必须的,因此仅仅只有ES可以被用来指向其他的地方。这种模式原本是为了与Intel 8085相容,导致程式设计师永无止尽的痛苦。

除了以上所说的,8086也拥有16-bit的32K(其变种 Intel 8088 是8-bit的64K)输入输出空间,以及一个由硬体支援的64K(一个区段)记忆体堆叠。只有words(2位元组)可以被推入到堆叠中。堆叠是由记忆体的上端往下成长,他的底端是由SS:SP指向。有256个中断,可以由硬体或是软体同时组成。中断是可以串连在一起,使用堆叠来储存返回被中断的程式位址。

16位元保护模式

Intel 80286可以在不改变任何东西下,支援8086的真实模式16位元软体,然而它也支援额外的工作模式称为保护模式,可以将可定址的实体记忆体扩充到16MB,可定址的虚拟记忆体最大到1GB。这是使用节区暂存器来储存在节区表格中的索引值。处理器中有两个这样的表格,分别为GDTLDT,每一个可以储存最多8192个节区的描述子,每一个节区可以给予最大到64KB的记忆体存取。节区表格提供一个24位元的基底位址英语Base address(base address),可以用此基底位址增加想要的偏移量来创造出一个绝对位址。此外,每一个节区可以被赋予四种权限等级中的一种(称为"rings")。

尽管这个推出的功能是一项进步,但是他们并没有被广泛地使用,因为保护模式的作业系统无法执行当时的真实模式软体。这样的能力只有在随后80386处理器的虚拟86模式中出现。

在同时,作业系统比如OS/2尝试使用类似乒乓的方法,让处理器在保护和真实模式间切换。这样都会让电脑变慢且不安全,像是在真实模式下的程式可以轻易地使电脑当机。OS/2也定义了限制性的程式设计规则允许"Family API"或"bound"程式可以在真实模式或保护模式下执行。然而这是给原本为保护模式下设计的程式有关,反之则不然。保护模式程式并不支援节区选择子和实体记忆体之间的关系。有时候会错误地相信在16位元保护模式下执行真实模式的程式,导致IBM必须选择使用Intel保留给BIOS的中断呼叫。事实上这类的程式使用任意的选择子数值和使用在上面提到的“节区运算”的方式有关。

这个问题也在Windows 3.x上出现。这个推出版本想要在16位元保护模式下执行程式,而先前的版本只能在真实模式下执行。理论上,如果Windows 1.x或2.x程式是写得“适当”且避免使用节区运算的方式,它就有可能在真实和保护模式两者下执行。Windows程式一般来说都会避免节区运算,这是因为Windows实作出软体的虚拟记忆体方式,及当程式不执行时候,搬移记忆体中的程式码和资料,所以操作绝对位址的方式是很危险的;当程式不执行时,被认为要保持记忆体区块的“handles”,这样的handles已经非常相当于保护模式的选择子。在保护模式下的Windows 3.0执行一个旧的程式,会触发一个警告对话盒,建议在真实模式下执行Windows(推测还是仍然可以使用扩充记忆体,可能是在80386机器用EMM386英语EMM386模拟,因此它并不被局限于640KB)或是从厂商那更新到新的版本。好的行为之程式可能可以使用特别的工具来避免这样的对话盒。不可能有些GUI程式在16位元保护模式下执行,且其它GUI程式在真实模式执行,可能是因为这会需要两个分开的环境且会依于前面所提到的处理器在两个模式间的乒乓效应。从Windows 3.1版开始,真实模式就消失了。

32位元保护模式

Intel 80386推出后,也许是到目前为止x86架构的最大跃进。除了需要值得注意的Intel 80386SX英语Intel_80386#The_80386SX_variant32位元架构但仅只有24位元英语24-bit_computing定址(和16位元资料汇流排)。除此之外其他架构都是32位元 - 所有的暂存器指令集、输出输入空间和记忆体定址。为了能够在后者所说的功能工作,要使用32位元扩充的保护模式。然而不像286,386所有的区段可以使用32位元的偏移量,即使记忆体空间有使用区段,但也允许应用程式存取超过4GB空间而不需要区段的分隔。此外,32位元保护模式提供分页的支援,是一种让虚拟记忆体得以实现的机制。

没有新的通用暂存器被加入。所有16位元暂存器除了区段暂存器外都扩充为32位元。Intel在暂存器的助记符号上加入“E”来表示(因此扩充的AX变成EAX,SI变成ESI,依此类推)。因为有更多的暂存器数量、指令、和运算单元,因此机器码的格式也被扩充。为了提供与先前的架构相容,包含执行码的区段可以被标示为16或是32位元的指令集。此外,特殊的前置符号也可以用来在16位元的区段包含32位元的指令码,反之亦然。

分页跟区段的记忆体存取是为了支援现在多工作业系统所必须要的。Linux386BSD英语386BSDWindows NTWindows 95都是一开始为386所发展,因为它是第一颗提供可靠地程式分离记忆体空间的支援(每个程式拥有自己的定址空间)以及可以在必要的情况下打断他们程式的执行(使用ring,一种x86保护模式下权力分级的名称)。这种386的基本架构变成未来所有x86系列发展的基础。

Intel 80386数学辅助运算处理器也在整合到这个CPU之后的x86系列中,也就是Intel 80486。新的FPU可以帮助浮点数运算,对于科学计算和图形设计是非常重要。

Intel首次在80386SL将系统管理模式引入x86体系结构。

虚拟86模式

功能扩充

MMX

1996年Intel的MMX(AMD认为这是矩阵数学扩充Matrix Math Extensions的缩写,但大多数时候都被当成Multi-Media Extension,而Intel从来没有官方宣布过词源)技术出现。尽管这项新的科技得到广泛宣传,但它的精髓是非常简单的:MMX定义了八个64位元SIMD暂存器,与Intel Pentium处理器的FPU堆叠有相重叠。不幸的是,这些指令无法非常简单地对应到由原来C编译器所产生的指令码中。MMX也只局限于整数的运算。这项技术的缺点导致MMX在它早期的存在有轻微的影响。现今,MMX通常是用在某些2D影片应用程式中。

3DNow!

1997年AMD推出3DNow!,是对于MMX的SIMD的浮点指令增强(针对相同的MMX暂存器)。尽管这些也没有解决编译器的难题,但这项技术的推出符合了PC上的3D休闲娱乐应用程式之崛起。3D游戏开发者和3D绘图硬体制造商在AMDAMD K6Athlon系列处理器上,使用3DNow!来帮助增加他们的效能。微软后来也在其开发的Direct X7.0中加入针对3DNow!的最佳化,使当时的Athlon处理器在3D游戏效能上首次全面超过对手英特尔Pentium 3处理器。

SSE

在1999年Intel推出SSE指令集,增加了八个新的128-bit暂存器(不跟其他的暂存器重叠使用)。这些指令类似于AMD的3DNow!,主要是增加浮点数运算的SIMD指令。

SSE2

2001年英特尔推出SSE2指令集,增加了:

  • 完整地补充了整数指令(与MMX相似)到原来的SSE暂存器。
  • 64位元的SIMD浮点运算指令到原来的SSE暂存器。

第一个的增加导致MMX几乎是过时可以舍弃的,第二个则允许这些指令可以让传统的编译器现实地产生。

SSE3

于2004年随著Pentium 4处理器的改版Prescott核心推出。SSE3增加特定的记忆体和thread-handling指令来提升Intel超执行绪的效能,在科学计算方面也有增强。

SSE4

2007年1月,Intel公开发表使用其45奈米制程"Penryn英语Penryn_(microarchitecture)"晶片家族的PC和伺服器。"Penryn"是这一系列依据英代尔Core微架构之笔记型电脑、桌上型电脑和伺服器晶片家族的代号,首次正式发布时共有16款处理器,除了一款Intel Core 2 Extreme QX9650是针对普通台式机市场外,其余的双核Xeon 5200系列和四核5400系列都是服务器处理器。基本上Penryn是继Merom英语Merom_(microprocessor)之后的缩小版Core 2 Duo,再加上47条新的SSE4指令集等额外配备。SSE4指令集之首次发表时间为2006年9月的英特尔开发者论坛(IDF,Intel Developer Forum)。

另外,x86处理器制造厂商AMD也在该公司K10架构的Phenom处理器中,加入4条新的SSE4A指令集。注意,SSE4与SSE4A无法彼此兼容。

AVX

FMA

AES

SHA

定址模式

定址模式在16-bit的x86处理器:

 

32-bit定址模式在32-bit或64-bit的x86处理器:

 

64-bit定址模式在64-bit的x86处理器:

 

x86汇编指令lea,是Load Effective Address的缩写,其优势是:

  • LEA指令具有单时钟周期,执行效率很高。
  • 是CPU地址生成单元参与运算的,而不是ALU参与运算的,所以在流水线上不会与上下文的算术逻辑指令产生流水相关
  • INTEL指令集中不存在很多RISC机器所具有的三操作数算术运算指令,比如像ARM的"add r0,r1,r2",而LEA指令恰好提供了同样的功能,以模拟“三元算术逻辑指令”。例如:lea ebx ,[eax+edx]
  • 在汇编语言程序设计中,在需要取得一个变量地址时,使用lea是很方便的。而mov指令则常常出错,因为在微软MASM汇编语法中,label和variable是不同的:addr不可前向引用,offset则能;addr可以处理局部变量而 offset则不能。

x86暂存器

16位元

自Intel 8086和8088起,有14个16位元暂存器。其中四个(AX, BX, CX, DX)是通用目的(尽管每个暂存器都有附加目的;举个例子:只有CX可以被用来当作loop回圈)指令的计数器。)每个暂存器可以被当成两个分开的位元组存取(因此BX的高位元可以被当成BH,低位元则可以当成BL)。除了这些暂存器,还有四个区段暂存器(CS、DS、SS、ES)。他们用来产生记忆体的绝对位址。还有两个指标暂存器(SP是指向堆叠的底部,BP可以用来指向堆叠或记忆体的其它地方)。两个指标暂存器(SI和DI)可以用来指向阵列的内部。最后,有旗标暂存器(包含状态旗标比如进位溢位、结果为零,等等)。以及IP是用来指向目前执行指令的位址。

32位元

自Intel 80386起,四个通用暂存器(EAX, EBX, ECX, EDX),它们较低的16位元分别与原本16位元的通用暂存器(AX, BX, CX, DX)重叠共用。指标暂存器(EIP, EBP, ESP, ESI, EDI)。区段暂存器除了原本的(CS、DS、SS、ES),另外新增(FS、GS),但是区段暂存器在32位元模式下改做为记忆体区块的选择子暂存器。旗标暂存器被扩展为32位元,较低的16位元与原本在16位元下的旗标暂存器重叠共用。

64位元

MMX暂存器(MM0~MM7),它们分别与浮点运算器〈FP0~FP7〉相重叠,所以MMX与浮点运算不可同时使用,必须透过切换选择要使用哪一种。

AMD64

英特尔原本已经决定在64位元的世代推出新的架构IA-64技术的Itanium处理器产品线来接替取代x86,但它与x86的软体天生不相容,因此藉以各种形式来执行x86的软体,不过,效率十分低下,加之处理器本身和软体移植的成本难以控制,因此这个计画最终告吹。

AMD自行把32位元x86(或称为IA-32)拓展为64位元,并命名为x86-64或Hammer架构,而后更名为AMD64架构,并曾禁止使用之前的名字来称呼这一架构[1]。以这个技术为基础的第一个产品是单核心的OpteronAthlon 64处理器家族。由于AMD的64位元处理器产品线首先进入市场,且微软也不愿意为英代尔代号为Yamhill的64位元版x86处理器开发第三个不同的64位元作业系统,英代尔被迫采纳AMD64架构且增加某些新的扩充到他们自己的产品,命名为EM64T架构(显然他们不想承认这些指令集是来自它的主要对手),EM64T后来被英代尔正式更名为Intel 64

这个架构也被称为 64位元拓展架构,即x64,譬如四个通用暂存器(RAX, RBX, RCX, RDX)是由32位元的(EAX, EBX, ECX, EDX)64位元扩展而来,相应的还有 指标暂存器(RIP, RBP, RSP, RSI, RDI),以及增加八个通用暂存器(R8~R15)等等。 这些资源只可在x64处理器的64位元模式下使用,在用来支援x86软体的遗留模式和相容模式中是不可见的。

128位元

SSE起,SIMD的暂存器XMM0 - XMM15.

256位元

SIMD registers YMM0 - YMM15.

512位元

SIMD registers ZMM0 - ZMM31.

暂存器结构

通用暂存器(A, B, C and D)
64 56 48 40 32 24 16 8
R?X
E?X
?X
?H ?L
在64位元模式新增的通用暂存器(R8, R9, R10, R11, R12, R13, R14, R15)
64 56 48 40 32 24 16 8
?
?D
?W
?B
区段暂存器(C, D, S, E, F and G)
16 8
?S
指标暂存器(S and B)
64 56 48 40 32 24 16 8
R?P
E?P
?P
?PL

Note: The ?PL registers are only available in 64-bit mode.

索引暂存器(S and D)
64 56 48 40 32 24 16 8
R?I
E?I
?I
?IL

Note: The ?IL registers are only available in 64-bit mode.

指令指标暂存器(I)
64 56 48 40 32 24 16 8
RIP
EIP
IP


虚拟化

Intel CPU的x86虚拟化技术有VT-x、VT-d等。AMD CPU的x86虚拟化技术有AMD-V等。

x86指令格式

x86与x86-64指令集的指令的格式为:

指令前缀 指令码 ModR/M SIB 偏移 直接数
Instruction Prefixes Opcode Displacement Immediate
可选。
最多4个单字节前缀。
任何顺序均可。
单字节、双字节、三字节 按需。
0-2位:R/M
3-5位:Reg/Opcode
6-7位:Mod
按需。
0-2位:Base
3-5位:Index
6-7位:Scale
0、1、2、4字节长 0、1、2、4字节长

指令前缀

分为4组,每组用1个字节编码。每组在指令中至多指定1个前缀值。4组的顺序可以任意。

  • 第1组锁与重复(Lock and repeat)
    • 锁(LOCK)编码为:F0H。用于互斥访问共享内存的操作。
    • 非零时重复(REPNE/REPNZ)编码为:F2H。用于字符串操作指令。
    • 为零时重复(REP/REPE/REPZ)编码为:F3H。用于字符串操作指令。
  • 第2组
    • 段覆盖(Segment override):CS、SS、DS、ES、FS、GS的段覆盖前缀的编码分别是2EH、36H、3EH、26H、64H、65H.
    • 分支提示(Branch hints),用于条件分支指令Jcc。提示分支不发生编码为2EH;提示分支发生编码为3EH。
  • 第3组操作数长度覆盖(Operand-size override)编码为66H。用于在16位与32位操作数切换。
  • 第4组地址长度覆盖(Address-size override)编码为67H.用于在16位与32位地址切换。

指令码

长度为1、2或3字节,此外ModR/M中还可能有3位。对于双字节指令码或三字节指令码,其中的第1个字节为0FH,用于与指令前缀区分。

ModR/M与SIB

许多指令的内存操作数需要使用ModR/M字节作为寻址模式说明符。其中的mod与r/m组合,共有32个值,表示8个寄存器与24种寻址模式。reg/opcode表示寄存器号或者额外的3位指令码,其具体含义依赖基本指令码。Mod与R/M的5位表示的第一操作数(源与目的操作数中寻址方式更复杂的那个操作数,指令码中的“方向位”direction bit(d)给出源或目的操作数哪个是第一操作数)的寻址方式如下:

寻址方式 Mod R/M
[EAX] 00 000
[ECX] 001
[EDX] 002
[EBX] 003
[--][--] 004
disp32 005
[ESI] 006
[EDI] 007
[EAX]+disp8 01 000
[ECX]+disp8 001
[EDX]+disp8 002
[EBX]+disp8 003
[--][--]+disp8 004
[EBP]+disp8 005
[ESI]+disp8 006
[EDI]+disp8 007
[EAX]+disp32 10 000
[ECX]+disp32 001
[EDX]+disp32 002
[EBX]+disp32 003
[--][--]+disp32 004
[EBP]+disp32 005
[ESI]+disp32 006
[EDI]+disp32 007
EAX/AX/AL/MM0/XMM0 11 000
ECX/CX/CL/MM/XMM1 001
EDX/DX/DL/MM2/XMM2 002
EBX/BX/BL/MM3/XMM3 003
ESP/SP/AH/MM4/XMM4 004
EBP/BP/CH/MM5/XMM5 005
ESI/SI/DH/MM6/XMM6 006
EDI/DI/BH/MM7/XMM7 007
1.[--][--]表示随后的SIB字节指明寻址方式;
2.Mod为11B时,表示寄存器操作数。对于R/M的每个值,根据指令码与操作数长度属性确定具体的寄存器号。
3.当指令需要第2操作数时,由Reg/Opcode的3位给出。第2操作数只能是寄存器操作数。寄存器的指定方式,与Mod为11B时指定作为第1操作数的寄存器的方式完全相同。

某些ModR/M字节表示的寻找模式,需要SIB字节来补充寻址方式。scale表示比例系数;index表示变址寄存器号;base表示基址寄存器号。使用scale与index的5位定义比例变址寄存器如下:

比例变址 Scale Index
[EAX] 00 000
[ECX] 001
[EDX] 002
[EBX] 003
004
[EBP] 005
[ESI] 006
[EDI] 007
[EAX*2] 01 000
[ECX*2] 001
[EDX*2] 002
[EBX*2] 003
004
[EBP*2] 005
[ESI*2] 006
[EDI*2] 007
[EAX*4] 10 000
[ECX*4] 001
[EDX*4] 002
[EBX*4] 003
004
[EBP*4] 005
[ESI*4] 006
[EDI*4] 007
[EAX*8] 11 000
[ECX*8] 001
[EDX*8] 002
[EBX*8] 003
004
[EBP*8] 005
[ESI*8] 006
[EDI*8] 007

3位base表示的基址寄存器号,定义如下:

EAX ECX EDX EBX ESP [*] ESI EDI
000 001 002 003 004 005 006 007
[*]有两种含义:1.如果Mod为00B,则[scaled index] + disp32,即没有基址寄存器。
2.如果Mod为01B或10B,表示基址寄存器为EBP。

在汇编程序设计中,一般把第1操作数的寻址方式总结为如下8种:

寻址方式 英文术语 举例
立即(数)寻址 immediate addressing mov EAX, 01F2H
寄存器寻址 register addressing mov EAX, ESI
直接寻址 direct addressing mov EAX, DWORD PTR [1FFA00H]
寄存器间接寻址 register indirect addressing mov EAX, DWORD PTR [EBX]
基址加变址寻址 base-plus-index addressing mov EAX, DWORD PTR [EBX+ESI]
寄存器相对寻址
或基址相对寻址
register relative addressing mov EAX, DWORD PTR [EDI+01F4H]
基址相对加变址寻址 base relative-plus-index addressing mov EAX, DWORD PTR 01F4H[EDI+EBX]
比例变址寻址 scaled-index addressing mov EAX, DWORD PTR 01F4H[EDI*8+EBX]

综合指令格式中的ModR/M与SIB两个字节的语义规定,指令的第1操作数的寻址方式可总结为4种物理实现:

  • 立即数:表示在指令的“立即数”部分。包括了直接寻址,即立即数作为内存的地址。
  • 寄存器操作数:Mod为11B,根据R/B部分的值、指令码、操作数长度属性,确定具体的寄存器号。
  • 基址相对寻址:即[Reg+disp8或disp32]。包括了寄存器间接寻址。这种情况计算第1操作数地址时使用了1个寄存器。
  • 基址加比例变址的相对寻址:即[BaseReg+IndexReg*scale+disp8或disp32]。这种情况计算第1操作数地址时使用了2个寄存器。

位移与立即数

某些寻址方式需要给出位移值。有些指令需要给出立即数作为操作数。

生产商

目前仍在设计、生产并贩卖x86处理器的公司包括:

曾经设计、生产并贩卖x86处理器,但现已退出x86处理器市场的公司包括:

参考文献

  1. ^ Rust, Adamson. AMD bans use of Hammer word, X86-64. The Inquirer. 2003-04-24 [2010-10-30]. (原始内容存档于2009-10-12). 

参见