x86
本条目部分链接不符合格式手冊規範。跨語言链接及章節標題等處的链接可能需要清理。(2015年12月13日) |
本条目需要精通或熟悉计算机科学的编者参与及协助编辑。(2013年7月7日) |
x86是一個指令集架構家族,最早由英特爾在1978年面市的「Intel 8086」CPU上開發出來。
該系列較早期的處理器名稱是以數字來表示80x86。由於以“86”作為結尾,包括Intel 8086、80186、80286、80386以及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集團、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弄混。
次代 | 發布日期 | 著名品牌 | 線性/物理地址空間 | 著名功能 |
---|---|---|---|---|
第一代 | 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 Bridge和Ivy 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)中(和相容的,比如微軟的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的助憶符號。
運作模式[编辑]
真實模式[编辑]
在真實模式下,記憶體的存取是被區段開來。為了得到最後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。這是使用節區暫存器來儲存在節區表格中的索引值。處理器中有兩個這樣的表格,分別為GDT和LDT,每一個可以儲存最多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 80386SX是32位元架構但僅只有24位元定址(和16位元資料匯流排)。除此之外其他架構都是32位元 - 所有的暫存器、指令集、輸出輸入空間和記憶體定址。為了能夠在後者所說的功能工作,要使用32位元擴充的保護模式。然而不像286,386所有的區段可以使用32位元的偏移量,即使記憶體空間有使用區段,但也允許應用程式存取超過4GB空間而不需要區段的分隔。此外,32位元保護模式提供分頁的支援,是一種讓虛擬記憶體得以實現的機制。
沒有新的通用暫存器被加入。所有16位元的暫存器除了區段暫存器外都擴充為32位元。Intel在暫存器的助記符號上加入“E”來表示(因此擴充的AX變成EAX,SI變成ESI,依此類推)。因為有更多的暫存器數量、指令、和運算單元,因此機器碼的格式也被擴充。為了提供與先前的架構相容,包含執行碼的區段可以被標示為16或是32位元的指令集。此外,特殊的前置符號也可以用來在16位元的區段包含32位元的指令碼,反之亦然。
分頁跟區段的記憶體存取是為了支援現在多工作業系統所必須要的。Linux、386BSD、Windows NT和Windows 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繪圖硬體製造商在AMD的AMD K6和Athlon系列處理器上,使用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處理器:
32-bit定址模式在32-bit或64-bit的x86處理器:
64-bit定址模式在64-bit的x86處理器:
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),且以這個技術為基礎的第一個產品是单核心的Opteron和Athlon 64處理器家族。由於AMD的64位處理器產品線首先进入市场,且微软也不愿意为英代爾和AMD开发两套不同的64位操作系统,英代爾也被迫采纳AMD64指令集且增加某些新的擴充到他們自己的產品,命名為EM64T架構(顯然他們不想承認這些指令集是來自它的主要對手),EM64T後來被英代爾正式更名為Intel 64。
這是由非Intel的製造商所發起和設計的第一次重大的x86架構升級。也許更重要的,它也是第一次Intel實際上從外部來源接受這項本質的技術。
128位元[编辑]
256位元[编辑]
SIMD registers YMM0 - YMM15.
512位元[编辑]
SIMD registers ZMM0 - ZMM31.
暫存器結構[编辑]
64 | 56 | 48 | 40 | 32 | 24 | 16 | 8 |
---|---|---|---|---|---|---|---|
R?X | |||||||
E?X | |||||||
?X | |||||||
?H | ?L |
64 | 56 | 48 | 40 | 32 | 24 | 16 | 8 |
---|---|---|---|---|---|---|---|
? | |||||||
?D | |||||||
?W | |||||||
?B |
16 | 8 |
---|---|
?S |
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.
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.
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處理器及其兼容產品,其中包括:
- 英特爾(Intel)
- 超微(AMD)
- Chips and Technologies
- 赛瑞克斯(被威盛電子收购)
- IBM
- IDT
- 國家半導體(NS,National Semiconductor)
- 日本電氣(NEC)
- NexGen(被超微收購)
- Rise Technology(被矽統科技收購)
- 意法半導體
- 矽統科技(SiS)
- 德州仪器(TI,Texas Instruments)
- 全美達(Transmeta)
- 聯華電子(UMC)
- 威盛電子(VIA)
- Movtalvo
- 瞻營全電子(DM&P)
(包含已退出x86市場的公司)
参见[编辑]
维基共享资源中相关的多媒体资源:X86 |
|
|