本頁使用了標題或全文手工轉換

x86

維基百科,自由的百科全書
前往: 導覽搜尋

x86是一個指令集架構家族,最早由英特爾在1978年面市的「Intel 8086CPU上開發出來。

該系列較早期的處理器名稱是以數字來表示80x86。由於以「86」作為結尾,包括Intel 8086801868028680386以及80486,因此其架構被稱為「x86」。由於數字並不能作為註冊商標,因此Intel及其競爭者均在新一代處理器使用可註冊的名稱,如Pentium。現時英特爾把x86-32稱為IA-32,全名為「Intel Architecture, 32-bit」;不過,由於x86包括16位元處理器,這樣的命名也出現麻煩。

歷史[編輯]

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弄混。

次代 發布日期 著名品牌 線性/實體位址空間 著名功能
第一代 1978年 Intel 8086, Intel 8088和其克隆 16位元/20位元 首個x86微處理器
1982年 Intel 80186, Intel 80188和其克隆, NEC V20/V30 引入用於快速計算位址資料和,快速乘除運算的硬體功能
第二代 Intel 80286和其克隆 16位元 / 24位元 引入用於在保護模式和較大位址空間記憶體管理單元,
第三代 (IA-32) 1985年 Intel 80386和其克隆, AMD Am386 32位元/32位元 32-bit 指令集、 具有分面功能的記憶體管理單元
三、四過渡代 1992年 Cyrix Cx486SLC, Cyrix Cx486DLC 一級緩存和流水化引入386平台
第四代 (浮點預算單元整合片中) 1989年 Intel 80486和其克隆, AMD Am486 類似於RISC的流水化, 整合的x87 浮點運算單元 (80位元), 片上CPU緩存
四、五過渡代 1997年 Am5x86, Cyrix 5x86, Pentium OverDrive 部分Pentium的功能被引入486平台
第五代 1993年 Pentium, Pentium MMX, Rise mP6 超標量 64位元 資料匯流排, 較快的浮點運算單元, MMX (2× 32-bit)
五、六過渡代 1996年 AMD K5, Cyrix 6x86, Cyrix MII, Nx586 (1994), IDT/Centaur-C6, Cyrix III-Samuel, VIA C3-Samuel2 / VIA C3-Ezra (2001) 分離式微架構(微代碼轉換)
第六代 1997 AMD K6/2/III 三級緩存的支援, 3DNow!
1995年 Pentium Pro, Cyrix III-Joshua (2000) 與上同 / 36位元實體位址 微代碼轉換, 條件性賦值指令, 亂序 暫存器重新命名揣測執行PAE (Pentium Pro), 片上二級緩存 (Pentium Pro)
1997年 Pentium II/III SSE (2× 64-bit)
六、七間隔代 2003年 Pentium M, VIA C7 (2005), Intel Core (2006) 為散熱功耗優化、四脈衝前端匯流排
第七代 1999年 Athlon, Athlon XP 超標量浮點運算單元,解碼三個x86指令每週期
2000年 Pentium 4 超深流水化,高頻率, SSE2超線程
七、八間隔代 2004年 Pentium 4 Prescott, Pentium D 64位元/40位元物理空間 特別超深流水化, 超高主頻, SSE3, 將64位元架構引入Pentium 4平台上, 片上多核心技術
第八代 2006年 Intel Core 2 64位元, 低功耗, 多核心, 低主頻, SSE4 (Penryn), 寬域動態執行,微碼整合,宏碼整合
2008年 VIA Nano 亂序,超標量,64位元, 其於硬體功能的加密,超低功耗; 適應性電源管理
2003年 Athlon 64, Opteron 如上同/40位元物理空間 x86-64指令集 , 片上記憶體控制器、 閃載匯流排
2007年 AMD Phenom, AMD Phenom II (2008) 如上同/48位元物理空間 單片四核心, SSE4a, 閃載匯流排3.0
八、九間隔代 2008 Intel Core i3, Core i5 and Core i7 如上同/40位元物理空間 快徑, 整合型記憶體控制單元,片上三線緩存,模塊化, 片上GPGPU整合或依附
Intel Atom 正序但高流水, 超低功耗, 一些型號僅32位元運算,片上GPU
2011年 AMD Bobcat 亂序, 64位元, 片上GPU; 低功耗(Bobcat)
AMD Llano 如上同/48位元物理空間
第9代 (GPU) 2011年 AMD Bulldozer and Trinity SSE5/AVX (4× 64-bit),高模塊化設計,整合片上GPU
Intel Sandy BridgeIvy Bridge 如上同/40位元物理空間
2013年 Intel Haswell 如上同/44位元物理空間 AVX2, FMA3, TSX, BMI1, and BMI2指令集
入境者 2012年 Intel Xeon Phi (Larrabee) (MIC pilot) 多個整型核心(62),正序P54C,64位元架構, 超寬 向量單元, LRBni指令(8× 64-bit)
2000年 Transmeta Crusoe, Transmeta Efficeon 32位元/32位元 帶有x86模擬器的VLIW的設計,整合記憶體控制器
2001年 Intel Itanium IA-32 相容模式 32位元 / N/A EPIC架構,片上IA-32執行層(2006年前產品),軟體模擬(2006年後產品)

設計[編輯]

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組合語言文章中有更詳細的討論。

運作模式[編輯]

真實模式[編輯]

在真實模式下,記憶體的存取是被區段開來。為了得到最後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),可以用此基底位址增加想要的偏移量來創造出一個絕對位址。此外,每一個節區可以被賦予四種權限等級中的一種(稱為"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模擬,因此它並不被局限於640KB)或是從廠商那更新到新的版本。好的行為之程式可能可以使用特別的工具來避免這樣的對話盒。不可能有些GUI程式在16位元保護模式下執行,且其它GUI程式在真實模式執行,可能是因為這會需要兩個分開的環境且會依於前面所提到的處理器在兩個模式間的桌球效應。從Windows 3.1版開始,真實模式就消失了。

32位元保護模式[編輯]

Intel 80386推出後,也許是到目前為止x86架構的最大躍進。除了需要值得注意的Intel 80386SX32位元架構但僅只有24位元定址(和16位元資料匯流排)。除此之外其他架構都是32位元 - 所有的暫存器指令集、輸出輸入空間和記憶體定址。為了能夠在後者所說的功能工作,要使用32位元擴充的保護模式。然而不像286,386所有的區段可以使用32位元的偏移量,即使記憶體空間有使用區段,但也允許應用程式存取超過4GB空間而不需要區段的分隔。此外,32位元保護模式提供分頁的支援,是一種讓虛擬記憶體得以實現的機制。

沒有新的通用暫存器被加入。所有16位元暫存器除了區段暫存器外都擴充為32位元。Intel在暫存器的助記符號上加入「E」來表示(因此擴充的AX變成EAX,SI變成ESI,依此類推)。因為有更多的暫存器數量、指令、和運算單元,因此機器碼的格式也被擴充。為了提供與先前的架構相容,包含執行碼的區段可以被標示為16或是32位元的指令集。此外,特殊的前置符號也可以用來在16位元的區段包含32位元的指令碼,反之亦然。

分頁跟區段的記憶體存取是為了支援現在多工作業系統所必須要的。Linux386BSDWindows 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"晶片家族的PC和伺服器。"Penryn"是這一系列依據英代爾Core微架構之筆記型電腦、桌上型電腦和伺服器晶片家族的代號,首次正式發行時共有16款處理器,除了一款Intel Core 2 Extreme QX9650是針對普通桌上型電腦市場外,其餘的雙核Xeon 5200系列和四核5400系列都是伺服器處理器。基本上Penryn是繼Merom之後的縮小版Core 2 Duo,再加上47條新的SSE4指令集等額外配備。SSE4指令集之首次發表時間為2006年9月的英特爾開發者論壇(IDF,Intel Developer Forum)。

另外,x86處理器製造廠商超微也在該公司K10架構的Phenom處理器中,加入4條新的SSE4A指令集。注意,SSE4與SSE4A無法彼此相容。

定址模式[編輯]

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


\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處理器:


\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處理器:


\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暫存器[編輯]

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與浮點運算不可同時使用,必須透過切換選擇要使用哪一種。

之後在x86正式導入64位元架構後,四個通用暫存器(RAX, RBX, RCX, RDX),它們較低的32位元分別與原本32位元的通用暫存器(EAX, EBX, ECX, EDX)重疊共用。指標暫存器(RIP, RBP, RSP, RSI, RDI)。以及增加八個通用暫存器(R8~R15)。

在2002年,由於32位元特性的長度,x86的架構開始到達某些設計的極限。這個導致要處理大量的資訊儲存大於4GB會有困難,像是在資料庫或是影片編輯上可以發現。

英特爾原本已經決定在64位元的世代完全地捨棄x86相容性,推出新的架構稱為IA-64技術作為他的Itanium處理器產品線的基礎。IA-64與x86的軟體天生不相容;它使用各種模擬形式來執行x86的軟體,不過,以模擬方式來執行的效率十分低下,並且會影響其他程式的執行。

超微主動把32位元x86(或稱為IA-32)擴充為64位元。它以一個稱為AMD64的架構出現(在重新命名前也稱為x86-64),且以這個技術為基礎的第一個產品是單核心的OpteronAthlon 64處理器家族。由於AMD的64位元處理器產品線首先進入市場,且微軟也不願意為英代爾和AMD開發兩套不同的64位元作業系統,英代爾也被迫採納AMD64指令集且增加某些新的擴充到他們自己的產品,命名為EM64T架構(顯然他們不想承認這些指令集是來自它的主要對手),EM64T後來被英代爾正式更名為Intel 64

這是由非Intel的製造商所發起和設計的第一次重大的x86架構升級。也許更重要的,它也是第一次Intel實際上從外部來源接受這項本質的技術。

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


虛擬[編輯]

虛擬x86是很簡單的,因為它的架構已經達到波佩克與戈德堡虛擬化需求。然而,有好幾個商業的虛擬x86產品,比如VMware微軟Virtual PC。Intel和AMD兩者都有公開宣布未來的x86處理器將會有新的增強來容易達到更有效率的虛擬。Intel針對這項虛擬特性的代號稱為"Vanderpool"和"Silvervale";AMD則使用"Pacifica"這個代號。

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市場的公司)

參見[編輯]