X86

x86泛指一系列基于Intel 8086且向后兼容的中央处理器指令集架构。最早的8086处理器于1978年由Intel推出，为16位微处理器。 該系列較早期的處理器名稱是以數字來表示80x86。由於以“86”作為結尾，包括Intel 8086、80186、80286、80386以及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集團、IBM、IDT以及Transmeta。Intel以外最成功的製造商為AMD，其早先产品Athlon系列處理器的市場份額僅次於Intel Pentium。 8086是16位元處理器；直到1985年32位元的80386的開發，這個架構都維持是16位元。接著一系列的處理器表示了32位元架構的細微改進，推出了數種的擴充，直到2003年AMD對於這個架構發展了64位元的擴充，并命名为AMD64。後來英特爾也推出了與之兼容的處理器，並命名為Intel 64。兩者一般被統稱為x86-64或x64，开创了x86的64位时代。 值得注意的是英特爾早在1990年代就与惠普合作提出了一种用在安腾系列处理器中的独立的64位架构，这种架构被称为IA-64。IA-64是一种崭新的系统，和x86架構完全没有相似性；不應該把它与x86-64或x64弄混。 x86架構是重要地可變指令長度的CISC（複雜指令集電腦，Complex Instruction Set Computer）。字組（word, 4位元組）長度的記憶體存取允許不對齊記憶體位址，字組是以低位字节在前的順序儲存在記憶體中。向後相容性及Intel量產製程經常領先業界一直都是在x86架構的發展背後一股驅動力量（設計的需要決定了這項因素而常常導致批評，尤其是來自對手處理器的擁護者和理論界，他們對於一個被廣泛認為是落后設計的架構的持續成功感到不解）。但在較新的微架構中，x86處理器會將常用的x86指令盡全力以硬體線路執行，不常用者則轉換為更像RISC的微指令再予执行，從而獲得可與RISC比擬的超純量性能，而仍然保持向後兼容。x86架構的處理器一共有四種執行模式，分别是真實模式，保護模式，系统管理模式以及虛擬V86模式。 在這篇簡短的文章中出現的指令和暫存器助憶符號的名稱，都在Intel文件中有所指定以及使用在Intel組譯器（Assembler）中（和相容的，比如微軟的MASM、Borland的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個中斷，可以由硬體或是軟體同時組成。中斷是可以串連在一起，使用堆疊來儲存返回被中斷的程式位址。 Intel 80286可以在不改變任何東西下，支援8086的真實模式16位元軟體，然而它也支援額外的工作模式稱為保護模式，可以將可定址的實體記憶體擴充到16MB，可定址的虛擬記憶體最大到1GB。這是使用節區暫存器來儲存在節區表格中的索引值。處理器中有兩個這樣的表格，分別為GDT和LDT，每一個可以儲存最多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版開始，真實模式就消失了。 Intel 80386推出後，也許是到目前為止x86架構的最大躍進。除了需要值得注意的Intel 80386SX（英语：Intel_80386#The_80386SX_variant）是32位元架構但僅只有24位元（英语：24-bit_computing）定址（和16位元資料匯流排）。除此之外其他架構都是32位元 - 所有的暫存器、指令集、輸出輸入空間和記憶體定址。為了能夠在後者所說的功能工作，要使用32位元擴充的保護模式。然而不像286，386所有的區段可以使用32位元的偏移量，即使記憶體空間有使用區段，但也允許應用程式存取超過4GB空間而不需要區段的分隔。此外，32位元保護模式提供分頁的支援，是一種讓虛擬記憶體得以實現的機制。 沒有新的通用暫存器被加入。所有16位元的暫存器除了區段暫存器外都擴充為32位元。Intel在暫存器的助記符號上加入“E”來表示（因此擴充的AX變成EAX，SI變成ESI，依此類推）。因為有更多的暫存器數量、指令、和運算單元，因此機器碼的格式也被擴充。為了提供與先前的架構相容，包含執行碼的區段可以被標示為16或是32位元的指令集。此外，特殊的前置符號也可以用來在16位元的區段包含32位元的指令碼，反之亦然。 分頁跟區段的記憶體存取是為了支援現在多工作業系統所必須要的。Linux、386BSD（英语：386BSD）、Windows NT和Windows 95都是一開始為386所發展，因為它是第一顆提供可靠地程式分離記憶體空間的支援（每個程式擁有自己的定址空間）以及可以在必要的情況下打斷他們程式的執行（使用ring，一種x86保護模式下權力分級的名稱）。這種386的基本架構變成未來所有x86系列發展的基礎。 Intel 80386數學輔助運算處理器也在整合到這個CPU之後的x86系列中，也就是Intel 80486。新的FPU可以幫助浮點數運算，對於科學計算和圖形設計是非常重要。 Intel首次在80386SL將系統管理模式引入x86体系结构。 1996年Intel的MMX（AMD认为这是矩陣數學擴充Matrix Math Extensions的缩写，但大多数時候都被當成Multi-Media Extension，而Intel从来没有官方宣布过词源）技術出現。儘管這項新的科技得到广泛宣传，但它的精髓是非常簡單的：MMX定義了八個64位元SIMD暫存器，與Intel Pentium處理器的FPU堆疊有相重疊。不幸的是，這些指令無法非常簡單地對應到由原來C編譯器所產生的指令碼中。MMX也只局限於整數的運算。這項技術的缺點導致MMX在它早期的存在有輕微的影響。現今，MMX通常是用在某些2D影片應用程式中。 1997年AMD推出3DNow!，是對於MMX的SIMD的浮點指令增強（針對相同的MMX暫存器）。儘管這些也沒有解決編譯器的難題，但這項技術的推出符合了PC上的3D休閒娛樂應用程式之崛起。3D遊戲開發者和3D繪圖硬體製造商在AMD的AMD K6和Athlon系列處理器上，使用3DNow!來幫助增加他們的效能。微軟後來也在其開發的Direct X7.0中加入針對3DNow!的最佳化，使當時的Athlon處理器在3D遊戲效能上首次全面超過對手英特爾的Pentium 3處理器。 在1999年Intel推出SSE指令集，增加了八個新的128-bit暫存器（不跟其他的暫存器重疊使用）。這些指令類似於AMD的3DNow!，主要是增加浮點數運算的SIMD指令。 2001年英特爾推出SSE2指令集，增加了： 完整地補充了整數指令（與MMX相似）到原來的SSE暫存器。 64位元的SIMD浮點運算指令到原來的SSE暫存器。 第一個的增加導致MMX幾乎是過時可以捨棄的，第二個則允許這些指令可以讓傳統的編譯器現實地產生。 於2004年隨著Pentium 4處理器的改版Prescott核心推出。SSE3增加特定的記憶體和thread-handling指令來提升Intel超執行緒的效能，在科學計算方面也有增强。 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無法彼此兼容。 定址模式在16-bit的x86處理器： { C S : D S : S S : E S : } [ { B X B P } ] + [ { S I D I } ] + [ d i s p l a c e m e n t ] {\displaystyle {\begin{Bmatrix}CS:\\DS:\\SS:\\ES:\end{Bmatrix}}{\begin{bmatrix}{\begin{Bmatrix}BX\\BP\end{Bmatrix}}\end{bmatrix}}+{\begin{bmatrix}{\begin{Bmatrix}SI\\DI\end{Bmatrix}}\end{bmatrix}}+{\rm {[displacement]}}} 32-bit定址模式在32-bit或64-bit的x86處理器： { C S : D S : S S : E S : F S : G S : } [ { E A X E B X E C X E D X E S P E B P E S I E D I } ] + [ { E A X E B X E C X E D X E B P E S I E D I } ∗ { 1 2 4 8 } ] + [ d i s p l a c e m e n t ] {\displaystyle {\begin{Bmatrix}CS:\\DS:\\SS:\\ES:\\FS:\\GS:\end{Bmatrix}}{\begin{bmatrix}{\begin{Bmatrix}EAX\\EBX\\ECX\\EDX\\ESP\\EBP\\ESI\\EDI\end{Bmatrix}}\end{bmatrix}}+{\begin{bmatrix}{\begin{Bmatrix}EAX\\EBX\\ECX\\EDX\\EBP\\ESI\\EDI\end{Bmatrix}}*{\begin{Bmatrix}1\\2\\4\\8\end{Bmatrix}}\end{bmatrix}}+{\rm {[displacement]}}} 64-bit定址模式在64-bit的x86處理器： { { F S : G S : } [ g e n e r a l r e g i s t e r ] + [ g e n e r a l r e g i s t e r ∗ { 1 2 4 8 } ] R I P } + [ d i s p l a c e m e n t ] {\displaystyle {\begin{Bmatrix}{\begin{Bmatrix}FS:\\GS:\end{Bmatrix}}{\begin{bmatrix}{\rm {general\;register}}\end{bmatrix}}+{\begin{bmatrix}{\rm {general\;register}}*{\begin{Bmatrix}1\\2\\4\\8\end{Bmatrix}}\end{bmatrix}}\\\\RIP\end{Bmatrix}}+{\rm {[displacement]}}} 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则不能。 自Intel 8086和8088起，有14個16位元暫存器。其中四個（AX, BX, CX, DX）是通用目的（儘管每個暫存器都有附加目的；舉個例子：只有CX可以被用來當作loop（迴圈）指令的計數器。）每個暫存器可以被當成兩個分開的位元組存取（因此BX的高位元可以被當成BH，低位元則可以當成BL）。除了這些暫存器，還有四個區段暫存器（CS、DS、SS、ES）。他們用來產生記憶體的絕對位址。還有兩個指標暫存器（SP是指向堆疊的底部，BP可以用來指向堆疊或記憶體的其它地方）。兩個指標暫存器（SI和DI）可以用來指向陣列的內部。最後，有旗標暫存器（包含狀態旗標比如進位、溢位、結果為零，等等）。以及IP是用來指向目前執行指令的位址。 自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位元下的旗標暫存器重疊共用。 MMX暫存器（MM0～MM7），它們分別與浮點運算器〈FP0～FP7〉相重疊，所以MMX與浮點運算不可同時使用，必須透過切換選擇要使用哪一種。 英特爾原本已經決定在64位元的世代推出新的架構IA-64技術的Itanium處理器產品線來接替取代x86，但它與x86的軟體天生不相容，因此藉以各種形式來執行x86的軟體，不过，效率十分低下，加之處理器本身和軟體移植的成本難以控制，因此這個計畫最終告吹。 AMD自行把32位元x86（或稱為IA-32）拓展為64位元，並命名為x86-64或Hammer架構，而後更名為AMD64架構，並曾禁止使用之前的名字來稱呼這一架構。以這個技術為基礎的第一個產品是单核心的Opteron和Athlon 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軟體的遺留模式和相容模式中是不可見的。 自SSE起，SIMD的暫存器XMM0 - XMM15. SIMD registers YMM0 - YMM15. SIMD registers ZMM0 - ZMM31. Note: The ?PL registers are only available in 64-bit mode. Note: The ?IL registers are only available in 64-bit mode. Intel CPU的x86虛擬化技術有VT-x、VT-d等。AMD CPU的x86虛擬化技術有AMD-V等。 x86与x86-64指令集的指令的格式为： 分为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字节作为寻址模式说明符。其中的mod与r/m组合，共有32个值，表示8个寄存器与24种寻址模式。reg/opcode表示寄存器号或者额外的3位指令码，其具体含义依赖基本指令码。Mod与R/M的5位表示的第一操作数（源与目的操作数中寻址方式更复杂的那个操作数，指令码中的“方向位”direction bit(d)给出源或目的操作数哪个是第一操作数）的寻址方式如下： 某些ModR/M字节表示的寻找模式，需要SIB字节来补充寻址方式。scale表示比例系数；index表示变址寄存器号；base表示基址寄存器号。使用scale与index的5位定义比例变址寄存器如下： 3位base表示的基址寄存器号，定义如下： 在汇编程序设计中，一般把第1操作数的寻址方式总结为如下8种： 综合指令格式中的ModR/M与SIB两个字节的语义规定，指令的第1操作数的寻址方式可总结为4种物理实现： 立即数：表示在指令的“立即数”部分。包括了直接寻址，即立即数作为内存的地址。 寄存器操作数：Mod为11B，根据R/B部分的值、指令码、操作数长度属性，确定具体的寄存器号。 基址相对寻址：即[Reg+disp8或disp32]。包括了寄存器间接寻址。这种情况计算第1操作数地址时使用了1个寄存器。 基址加比例变址的相对寻址：即[BaseReg+IndexReg*scale+disp8或disp32]。这种情况计算第1操作数地址时使用了2个寄存器。 某些寻址方式需要给出位移值。有些指令需要给出立即数作为操作数。 目前仍在設計、生產並販賣x86處理器的公司包括： 英特爾（Intel） 超微（AMD） 瞻營全電子（DMP Electronics INC.） 威盛電子（VIA） 兆芯 曾經設計、生產並販賣x86處理器，但現已退出x86處理器市場的公司包括： Chips and Technologies Cyrix（被威盛電子收购） IBM IDT 國家半導體（NS，National Semiconductor） 日本電氣（NEC） NexGen（被超微收購） Rise Technology（被矽統科技收購） 意法半導體 矽統科技（SiS） 德州仪器（Texas Instruments） 全美達（Transmeta） 聯華電子（UMC） Montalvo（英语：Montalvo_Systems） Rust, Adamson. AMD bans use of Hammer word, X86-64. The Inquirer. 2003-04-24 [2010-10-30]. （原始内容存档于2009-10-12）.  维基共享资源上的相关多媒体资源：X86