Intel 8086
![本頁使用了標題或全文手工轉換](http://images.weserv.nl/?url=//upload.wikimedia.org/wikipedia/commons/thumb/c/cd/Zh_conversion_icon_m.svg/35px-Zh_conversion_icon_m.svg.png)
![]() | |
產品化 | 1978年至1990年代 |
---|---|
生產商 | |
指令集架構 | x86-16 |
製作工藝/製程 | 3 μm |
CPU主頻範圍 | 5 MHz 至 10 MHz |
封裝 |
|
上代產品 | Intel 8080 |
繼任產品 | 80186和80286(兩種晶片均在1982年引進) |
相關產品 | 8088 |
Intel 8086[1](亦稱之為iAPX 86)[2]是由英特爾公司於1976年初開始設計,1978年年中發表的Intel第一款16位元微處理器。隨後於1979年,又推出了Intel 8088,它在晶片的外部連接椎使用8位元資料匯流排(允許使用更廉價和更少集成電路[note 1])的支援,成為8086的一個低成本的簡化產品,並用在IBM PC的原始設計中的處理器(包括廣為人所知的IBM PC XT)中而被人知曉。
8086是Intel最成功的處理器系列x86架構的開端。
歷史
背景
1972年,Intel發表了8008微處理器——世界上第一款8位元微處理器。[note 2] 8008微處理器有18個引腳,其中地址匯流排使用了14個引腳,並且與8位元數據匯流排復用引腳。指令集源自是Datapoint公司為電腦的CRT-鍵盤終端設計的但相當通用的指令集。當時英特爾還是一家生產DRAM為主業的公司,缺乏這方面的技術儲備。
1974年,Intel發表了8080微處理器,[note 3] 被公認是第一款真正可用的微處理器。8080的晶片封裝採用40個引腳,其中8個數據匯流排引腳、16個地址匯流排引腳都是專用的,因此數據匯流排與地址匯流排可以並列工作。8080的擴充後的指令集在原始碼級別上向前相容8008指令集。
1975年,Intel發表了第三款8位元微處理器——8085。採用了新的製造工藝,簡化了輸入電壓引腳的數量。同一時期還有Motorola 6800(1974)、Microchip PIC16X(1975)、MOS Technology 6502(1975)、Zilog Z80(1976)及Motorola 6809(1978)等8位元微處理器。在8位元微處理器市場競爭中Z80最為成功。
第一種x86設計
8086專案起始於1976年5月,是英特爾公司當時更為看重的16位元的iAPX 432微處理器的備份專案。8086一方面要與Motorola, Zilog, National Semiconductor等公司的16位元、32位元微處理器競爭市佔率,另一方面也是對Zilog Z80在8位元位微處理器市場上的成功的回擊。由於採用了與8085微處理器近似的微體系結構與物理實現工藝製程,8086專案進展相當快。
8086微處理器被設計為在組譯源程式上向前相容8008, 8080, 8085等微處理器。指令集與編程模式是基於8080微處理器,但指令集做了擴充以完全支援16位元運算。
新增加的指令包括:完全支援有符號整數、段基址+偏移量定址、類似於Z80的[3]自重複操作、直接支援巢狀的ALGOL類語言如Pascal或PL/M、微碼實現的乘法除法指令、以及更好支援與協處理器(8087或8089)和多處理器系統的匯流排結構。
第一版的指令集與高層的體系結構的設計僅用了3個月。[note 4] 在沒有CAD工具的時代,4名工程師與12名布線繪圖員平行工作,[note 5] 用了2年多的時間才把8086的高層設計實現為可執行測試的產品。這在當時算是很快的研發速度。
8086是隨機邏輯[4]與微碼的混合實現[note 6],使用了大約20,000個電晶體(算上所有的ROM與可程式化邏輯陣列為29,000個電晶體)。晶片面積為33 mm²,製程為3.2 μm.
8086體系結構由Stephen P. Morse設計,並在最後定案時得到Bruce Ravenel(8087體系結構設計者)的幫助。邏輯設計者是以Jim McKevitt與John Bayliss為首的硬件開發工程師團隊[note 7]。專案經理William Pohlman。迄今8086的指令集仍然是個人電腦與伺服器的基本指令集。
細節
Intel 8086暫存器 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
匯流排與操作
所有的內部暫存器、內部及外部數據匯流排都是16位元寬,因此是完全的16位元微處理器。20位外部地址匯流排,因此物理定址空間為1MiB (即220 = 1,048,576).由於內部暫存器都是16位元,對1M地址空間定址時採取了段定址方式。8086的封裝採用40引腳的雙列直插(dual in-line),數據匯流排與地址匯流排復用了前16個引腳。16位元的I/O地址,因此獨立的I/O定址空間為64KiB的虛擬定址空間 (即216 = 65,536).由於8086內部的地址暫存器是16 位寬,因而最大線性定址空間為64 KiB.使用超過64 KiB主記憶體空間的程式設計時,需要調整段暫存器(segment registers)。直到32位元的80386出現之前,8086的這種段定址相當不便.
8086晶片封裝的8個控制引腳在min或max下有不同功能。"min"模式是使用單處理器的小型電腦系統,"max"模式是使用多處理器的中到大型電腦系統。
暫存器與指令
8086有8個16位元的暫存器,包括棧暫存器SP與BP,但不包括指令暫存器IP、控制暫存器FLAGS以及四個段暫存器。AX, BX, CX, DX,這四個暫存器可以按照位元組訪問;但BP, SI, DI, SP,這四個地址暫存器只能按照16位元寬訪問。
8086以8080和8085(它與8080有組譯語言上的原始碼相容性)的設計為基礎,擁有類似的暫存器集合,但是擴充為16位元。匯流排介面單元(Bus Interface Unit)透過6位元組預存(prefetch)的貯列(queue)將指令送給執行單元(Execution Unit),所以取指令和執行是同步的-一種管線化的原始形式(8086指令長度變化從1到6位元組)。
8086有四個完全一樣的16位元暫存器,但也能夠當作八個8位元暫存器來存取;以及四個16位元索引暫存器(包含堆疊索引)。數據暫存器通常由指令隱含地使用,針對暫存值需要複雜的暫存器組態。它提供64K 8位元的輸出輸入(或32K 16位元)埠,以及固定的向量中斷。大部分的指令只能夠存取一個記憶體地址,所以其中一個運算子必須是一個暫存器。運算結果會儲存在運算子中的一個。
8086有4個記憶體區段(segment)暫存器,可以通過索引暫存器來設置。區段暫存器可以讓CPU一種當時是全新的方式存取多達1MB之記憶體。在現今有區段的處理器中,8086把區段暫存器左移4位元然後把它加上去定址。這通常被認為是一個不太好的設計,因為這麼做會讓各區段有重疊。儘管這樣對於組譯語言而言會顯得有用——因為可以充分控制區段,但同時卻使高階語言中的指標(像是C程式語言)使用變得困難。它降低了指標的高效率,且有可能產生兩個指向同一個地方的指標擁有不同的地址。更壞的是,這種方式產生要讓記憶體擴充到大於1MB的困難。而80286的定址方式改變讓記憶體擴充較有效率。
由於8位元機(如Intel 8008)時代沿襲下來的緊湊編碼,大多數指令雖然有兩個源運算元(operands)及一個輸出結果,但單條指令至多使用兩個地址,因此運算結果被存入一個源運算元中。且最多只能有一個主記憶體運算元,另外的運算元是暫存器或立即數。主記憶體運算元也可以用於儲存指令的輸出結果。8位元微處理器的指令集不能把輸出結果直接儲存在主記憶體運算元中,因此8086指令集的如此設計大大提高了代碼密度(code density)。
相比與8080或8085,8086有更強的暫存器通用性,但比起典型的小型電腦來說仍有很大不如。8086的某些指令隱式使用某些暫存器。比起更為規則的16- 或32-位處理器如PDP-11, VAX, 68000,等等,8086的暫存器分配特性使得編譯器的工作更為複雜;另一方面,比起半現代化的但廣為使用的8位元微處理器如6502, 6809,或8085,編譯器生成代碼就容易太多了.
8086有64 KiB的字寬為8位元的(或32K個寬度為16位元的)I/O定址空間.
棧的長度最大為64 KB(一個段) ,8086硬件支援棧頂由高地址向低地址生長。入棧、彈棧的數據單元長度為2位元組。棧頂位置由暫存器的組合SS:SP給出.
共有256 個中斷,包括硬件中斷與軟中斷。中斷可以巢狀,使用棧來儲存中斷返回地址。
8086增加了一些8080與8085所沒有的新指令,用於更好地支援Pascal與PL/M的進階程式設計特性;如push mem-op, ret size, (其它一些指令如push immed and enter,在隨後的80186, 80286, and 80386中陸續增加.)
標誌暫存器
8086有一個16位元寬的標誌暫存器FLAGS.其中9個位元是被使用的,另外7個位元保留未用。具體是:進位標誌CF、奇偶標誌PF、輔助標誌AF、為零標誌ZF、符號標誌SF、追蹤標誌TF、中斷允許標誌IF、方向標誌DF、溢位標誌OF。
主記憶體分段
在Intel的8位元、16位元處理器中,由於暫存器的寬度為8或16位元,而地址匯流排的寬度一般是要大於暫存器的寬度,所以為了能訪問整個地址空間,需要採取特殊的定址計算——分段定址。從80386開始的32位元微處理器,地址匯流排寬度也是32位元,可以視作扁平(flat)地址空間,不再需要分段定址。
8086的分段定址,是指一個實體位址由段地址(segment selector)與偏移量(offset)兩部分組成,長度各是16位元。其中段地址左移4位元(即乘以16)與偏移量相加即為實體位址。例如,06EFh:1234h,表示段地址為06EFh,偏移量為1234h,實體位址為06EF0h + 1234h = 08124h。在計算實體位址時如果發生上溢位,8086處理器捨棄進位。例如,FFFFh:0010h所對應的實體位址為00000h.
一個20位的實體位址對應着4096個不同的"段地址:偏移量"的組合。這是因為,偏移量的最低4位元對應於實體位址的最低四位,而偏移量的高12位元共有4096個取值。
段地址所對應的實體位址的粒度是16位元組(=24),稱之為paragraph。
段地址確定後,偏移量的取值最多為64KiB(=65536),這就是分段定址的最大的線性地址空間。實際上在8086處理器上,作業系統分配的線性地址空間可以是不大於64KiB的任意數量。程式可以自由訪問整個實體記憶體空間,作業系統沒有任何權限限制或監管(supervision)。
8086處理器有20根地址匯流排引腳(pins),因此實體記憶體空間最大為220=1MiB=1,048,576位元組。這還包括了IO主記憶體。因此使用8086處理器的電腦的主記憶體的容量少於1MiB,最常見的主記憶體容量是640KiB。
由於X86指令集的向下相容原則,計算實體位址時,段地址左移4位元被所有後繼支援真實模式的X86處理器所繼承。80286是使用24位元寬地址匯流排的16位元微處理器,如果要在整個224=16MiB物理儲存空間定址,就必須採用其它方式,即保護模式定址,這時16位元的段地址是指向段描述符表(segment descriptors table)的一個包含24位元基地址的條目,基地址加上16位元偏移量即為24位元的實體位址。
在8086上執行的編譯器,一般支援兩種C語言的指標:近指標(near)與遠指標(far)。近指標是16位元的地址偏移值,隱式與程式的代碼段地址或數據段地址結合使用以確定實體位址。遠指標是32位元的「段地址:偏置量」成對出現,用以確定20位的實體位址。某些編譯器支援「巨指標」(huge),類似於遠指標。但巨指標的地址運算是線性20位;而遠指標的地址運算在16位元偏移值溢位時不影響段地址部分,因此遠指標的線性部分是16位元。
為了避免對大量的指標、數據結構、函數指出是「近」還是「遠」,編譯器提供了主記憶體模式(memory model)給出了預設的主記憶體訪問方式:
- 微模式tiny數據段代碼段共用不超過64K主記憶體空間,編譯為.com可執行檔案;
- 小模式small數據段、代碼段各用最多64K主記憶體共空間;
- 緊湊模式compact數據段> 64K;
- 中模式medium代碼段> 64K;
- 大模式large代碼段數據段都> 64K;
- 巨模式huge單個陣列> 64K。
預編譯庫對不同的主記憶體模式要分別編譯為相應版本。
移植老的程式
8位元機上的程式可以不考慮段地址直接以.com可執行檔案以「微模式」在8086上執行。這是當時8086與MS-DOS作為新平台取得市場成功的關鍵原因——大量已存的CP/M應用程式能很快得到利用。
實例代碼
以下8086/8088組譯原始碼是將給定大小的數據塊從一個位置拷貝到另一個位置的叫做_memcpy
的子程式。每次拷貝一個位元組,數據移動和迴圈邏輯採用16位元操作。
0000:1000 0000:1000 0000:1000 55 0000:1001 89 E5 0000:1003 06 0000:1004 8B 4E 06 0000:1007 E3 11 0000:1009 8B 76 04 0000:100C 8B 7E 02 0000:100F 1E 0000:1010 07 0000:1011 8A 04 0000:1013 88 05 0000:1015 46 0000:1016 47 0000:1017 49 0000:1018 75 F7 0000:101A 07 0000:101B 5D 0000:101C 29 C0 0000:101E C3 0000:101F |
; _memcpy(dst, src, len)
; Copy a block of memory from one location to another.
;
; Entry stack parameters
; [BP+6] = len, Number of bytes to copy
; [BP+4] = src, Address of source data block
; [BP+2] = dst, Address of target data block
;
; Return registers
; AX = Zero
org 1000h ; Start at 0000:1000h
_memcpy proc
push bp ; Set up the call frame
mov bp,sp
push es ; Save ES
mov cx,[bp+6] ; Set CX = len
jcxz done ; If len=0, return
mov si,[bp+4] ; Set SI = src
mov di,[bp+2] ; Set DI = dst
push ds ; Set ES = DS
pop es
loop mov al,[si] ; Load AL from [src]
mov [di],al ; Store AL to [dst]
inc si ; Increment src
inc di ; Increment dst
dec cx ; Decrement len
jnz loop ; Repeat the loop
done pop es ; Restore ES
pop bp ; Restore previous call frame
sub ax,ax ; Set AX = 0
ret ; Return
end proc
|
上面的代碼使用BP(基指標)暫存器建立一個呼叫幀(包含子程式執行過程中的所有參數和局部變數的棧的區域)。這種呼叫約定支援可重入和遞歸代碼,大多數類ALGOL語言上世紀50年代後期就已採用這種約定。ES段暫存器儲存在堆疊上,並用DS段暫存器中的值替換,於是指令MOV
AL
會在相同的源數據段和目的數據段之間操作。在返回前,子程式恢復了ES暫存器以前的值。
上面的子程式是一種比較麻煩的拷貝成塊數據的方法。若源數據區域和目的數據區域都是處於單個65,536位元組的段中(上述程式的要求),使用8086的塊MOV
指令更有優勢。上面的迴圈部分可以替換為:
0000:1011 F2 0000:1012 A5 |
loop rep ; Repeat until CX=0
movsw ; Move the data block
|
這種方法每次可以拷貝一個字。REP
指令使下面的MOVSW
重複直至CX=0,重複之時自動遞增SI和DI。另外,MOVSB
或MOVSD
指令可以用來一次拷貝單個位元組或雙字。大多數組譯器在REP
指令用在MOVSW
之前為REP MOVSW
的情況下都會正確組譯。
如果被中斷,這個程式也能正確執行,因為程式計數器會繼續指向REP
指令,知道塊拷貝已經結束。拷貝會在中斷服務程式將控制恢復的時候繼續。
效能
![](http://images.weserv.nl/?url=//upload.wikimedia.org/wikipedia/commons/thumb/f/f7/Intel_8086_block_scheme.svg/405px-Intel_8086_block_scheme.svg.png)
外部匯流排作為數據與地址的復用,降低了CPU的效能。取16位元或8位元數據需要4個時鐘周期。指令的長度為1-6個位元組,取指令與執行是並行完成的。CPU內的匯流排介面單元把取到的指令儲存在6位元組的預取佇列中。
指令 | register-register | register immediate | register-memory | memory-register | memory-immediate |
---|---|---|---|---|---|
mov | 2 | 4 | 8+EA | 9+EA | 10+EA |
ALU | 3 | 4 | 9+EA, | 16+EA, | 17+EA |
jump | register => 11 ; label => 15 ; condition,label => 16 | ||||
整數乘法 | 70~160(取決於運算元data以及大小)加上EA | ||||
有符號整數除法 | 80~190(取決於運算元data以及大小)加上EA |
- EA = 計算有效地址的時間,5到12周期.
- 用時為最好的情形,依賴於預取狀態,指令對齊,及其它因素.
8086涉及主記憶體訪問的指令,包括跳轉(jump)指令需要比8080與8085更多的時間,原因在於:
- 取指令與執行指令是鬆散耦合,對於跳轉與亂數據訪問沒有特殊措施,效率較低.
- 沒有專門的地址計算部件,只能用主ALU,雖然有專用的段地址 + 偏移地址的加法器
- 外部地址匯流排與數據匯流排是多工復用,與8位元處理器相比要多用33~50%的匯流排周期
8086的後繼處理器的主記憶體訪問效能大大增強了。80186與80286有專門的地址計算硬件,節約了很多時間周期。80286的外部地址匯流排與數據匯流排是分開各自專用的。
浮點
8086/8088可以連接上專用的數學協處理器以增加浮點計算效能。標準的數學協處理是Intel 8087,執行80位元浮點數運算。
微電腦
第一個以8086為基礎的商業微電腦是Mycron2000。
IBM Displaywriter文字處理機也使用8086。在大部分顯要的所有微處理器中,IBM PC使用了更窄的記憶體總線版本的8086,也就是Intel 8088。 8086CPU結構上的一個重要特點是分為二大部分,即總線介面單元BIU和執行單元EU,其中BIU負責外部資訊交換,EU負責指令執行,二者合理分工、並行工作,工作效率比此前的CPU明顯提高,常稱之為流水線結構。
硬件模式
8086和8088支援兩種硬件模式:最大模式和最小模式。最大模式是用在大型應用中的多重處理,並且也是支援8087處理器的必需。該模式通常硬件化在電路中,不能由軟件改變。具體來說,#33引腳(MN/MX)是連載高電壓還是接地決定了模式。改變引腳#33的狀態就改變了其他特定引腳的功能,這些引腳中大多數是CPU處理(局部)匯流排的。IBM PC和PC/XT使用工作在最大模式的Intel 8088,讓CPU與PC或PC/XT主機板上安裝在數學協同處理器插口的可選8087協同處理器。(PC和PC/XT可能因為其他原因而要求用最大模式,比如要支援DMA控制器。)
外設
- Intel 8237:直接記憶體存取(DMA)控制器
- Intel 8251:USART
- Intel 8253:可程式化間隔定時器
- Intel 8255:可程式化序外圍介面
- Intel 8259:可程式化中斷控制器
- Intel 8279:鍵盤/顯示控制器
- Intel 8282/8283:8位元鎖存器
- Intel 8284:時鐘發生器
- Intel 8286/8287:雙向8位元驅動
- Intel 8288:匯流排控制器
- Intel 8289:匯流排仲裁器
紀念
2018年6月8日,英特爾在官網上開啟了限量抽獎活動,獎品為i7-8086k,限量生產8086個。
註釋
- ^ Fewer TTL buffers, latches, multiplexers (although the amount of TTL logic was not drastically reduced). It also permitted the use of cheap 8080-family ICs, where the 8254 CTC, 8255 PIO, and 8259 PIC were used in the IBM PC design. In addition, it made PCB layout simpler and boards cheaper, as well as demanding fewer (1- or 4-bit wide) DRAM chips.
- ^ using enhancement load PMOS logic (requiring 14 V, achieving TTL compatibility by having VCC at +5 V and VDD at –9 V)
- ^ using non-saturated enhancement load NMOS logic (demanding a higher gate voltage for the load transistor gates)
- ^ Rev.0 of the instruction set and architecture was ready in about three months, according to Morse.
- ^ Using rubylith, light boards, rulers, electric erasers, and a digitizer (according to Jenny Hernandez, member of the 8086 design team, in a statement made on Intel's webpage for its 25th birthday).
- ^ 8086 used less microcode than many competitors' designs, such as the MC68000 and others
- ^ Other members of the design team were Peter A.Stoll and Jenny Hernandez.
參考文獻
- ^ Microprocessor Hall of Fame. Intel. [2007-08-11]. (原始內容存檔於2007-07-06).
- ^ Official Intel iAPX 286 programmers' manual (頁面存檔備份,存於互聯網檔案館) (page 1-1)
- ^ Birth of a Standard: The Intel 8086 Microprocessor. Thirty years ago, Intel released the 8086 processor, introducing the x86 architecture that underlies every PC — Windows, Mac, or Linux — produced today (頁面存檔備份,存於互聯網檔案館), PC World, June 17, 2008
- ^ Randall L. Geiger, Phillip E. Allen, Noel R. Strader VLSI design techniques for analog and digital circuits, McGraw-Hill Book Co., 1990, ISBN 978-0-07-023253-2, page 779 "Random Logic vs. Structured Logic Forms", illustration of use of "random" describing CPU control logic
- ^ Microsoft Macro Assembler 5.0 Reference Manual. Microsoft Corporation. 1987.
Timings and encodings in this manual are used with permission of Intel and come from the following publications: Intel Corporation. iAPX 86, 88, 186 and 188 User's Manual, Programmer's Reference, Santa Clara, Calif. 1986.
(Similarly for iAPX 286, 80386, 80387.)
外部連結
|
Article based on Intel 8086 at FOLDOC(頁面存檔備份,存於互聯網檔案館),used with permission.
|