Intel 8086

Intel i7-8086K}}

Intel 8086（亦稱之為 iAPX 86）是由英特爾公司於 1976 年初開始設計，1978 年年中發表的 Intel 第一款 16 位元微處理器。隨後於 1979 年，又推出了 Intel 8088，它在晶片的外部連線椎使用 8 位資料匯流排（允許使用更廉價和更少積體電路）的支援，成為 8086 的一個低成本的簡化產品，並用在 IBM PC 的原始設計中的處理器（包括廣為人所知的 IBM PC XT）中而被人知曉。

8086 是 Intel 最成功的處理器系列 x86 架構的開端。

歷史

1.1 背景

1972 年，Intel 釋出了 8008 微處理器 —— 世界上第一款 8 位微處理器。 8008 微處理器有 18 個引腳，其中地址匯流排使用了 14 個引腳，並且與 8 位資料匯流排複用引腳。指令集源自是 Datapoint 公司為計算機的 CRT - 鍵盤終端設計的但相當通用的指令集。當時英特爾還是一家生產 DRAM 為主業的公司，缺乏這方面的技術儲備。

1974 年，Intel 釋出了 8080 微處理器， 被公認是第一款真正可用的微處理器。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 最為成功。

1.2 第一種 x86 設計

8086 專案起始於 1976 年 5 月，是英特爾公司當時更為看重的 16 位元的微處理器的備份專案。8086 一方面要與 Motorola, Zilog, National Semiconductor 等公司的 16 位元、32 位元微處理器競爭市場份額，另一方面也是對 Zilog Z80 在 8 位元位微處理器市場上的成功的回擊。由於採用了與 8085 微處理器近似的微體系結構與物理實現工藝物理實現工藝，8086 專案進展相當快。

8086 微處理器被設計為在彙編源程式上向前相容 8008, 8080, 8085 等微處理器。指令集與程式設計模式是基於 8080 微處理器，但指令集做了擴充以完全支援 16 位元計算。

新增加的指令包括：完全支援有符號整數、段基址 + 偏移量定址、類似於 Z80 的自重複操作、直接支援巢狀的 ALGOL 類語言如 Pascal 或 PL/M、微碼實現的乘法除法指令、以及更好支援與協處理器（8087 或 8089）和多處理器系統的匯流排結構。

第一版的指令集與高層的體系結構的設計僅用了 3 個月。 在沒有 CAD 工具的時代，4 名工程師與 12 名佈線繪圖員平行工作， 用了 2 年多的時間才把 8086 的高層設計實現為可執行測試的產品。這在當時算是很快的研發速度。

8086 是隨機邏輯與微碼的混合實現，使用了大約 20,000 個電晶體（算上所有的 ROM 與可程式設計邏輯陣列為 29,000 個電晶體）。芯片面積為 33 mm²，製造工藝為 3.2 μm.

8086 體系結構由 Stephen P. Morse 設計，並在最後定案時得到 Bruce Ravenel（8087 體系結構設計者）的幫助。邏輯設計者是以 Jim McKevitt 與 John Bayliss 為首的硬體開發工程師團隊。專案經理 William Pohlman。迄今 8086 的指令集仍然是 PC 機與伺服器的基本指令集。

細節

2.1 匯流排與操作

所有的內部暫存器、內部及外部資料匯流排都是 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位寬，因而最大線性定址空間為 64KiB. 使用超過 64KiB 記憶體空間的程式設計時，需要調整段暫存器（segment registers）。直到 32 位的 80386 出現之前，8086 的這種段定址相當不便.

8086 晶片封裝的 8 個控制引腳在 min 或 max 下有不同功能。"min" 模式是使用單處理器的小型計算機系統，"max" 模式是使用多處理器的中到大型計算機系統。

2.2 暫存器與指令

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 有 64KiB 的字寬為 8 位的（或 32K 個寬度為 16 位的）I/O 定址空間.

棧的長度最大為 64KB（一個段） ，8086 硬體支援棧頂由高地址向低地址生長。入棧、彈棧的資料單元長度為 2 位元組。棧頂位置由暫存器的組合 SS:SP 給出.

共有 256箇中斷，包括硬體中斷與軟中斷。中斷可以巢狀，使用棧來儲存中斷返回地址。

8086 增加了一些 8080 與 8085 所沒有的新指令，用於更好地支援 Pascal 與 PL/M 的高階程式設計特性；如 push mem-op, ret size, (其它一些指令如 push immed and enter, 在隨後的 80186, 80286, and 80386 中陸續增加.)

2.3 標誌暫存器

8086 有一個 16 位寬的標誌暫存器 FLAGS. 其中 9 個位元是被使用的，另外 7 個位元保留未用。具體是：進位標誌 CF、奇偶標誌 PF、輔助標誌 AF、為零標誌 ZF、符號標誌 SF、追蹤標誌 TF、中斷允許標誌 IF、方向標誌 DF、溢位標誌 OF。

2.4 記憶體分段

在 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。

預編譯庫對不同的記憶體模式要分別編譯為相應版本。

2.4.1 移植老的程式

8 位機上的程式可以不考慮段地址直接以.com 可執行檔案以 “微模式” 在 8086 上執行。這是當時 8086 與 MS-DOS 作為新平臺取得市場成功的關鍵原因 —— 大量已存的 CP/M 應用程式能很快得到利用。

2.5 例項程式碼

以下 8086/8088 彙編原始碼是將給定大小的資料塊從一個位置複製到另一個位置的叫做_memcpy 的子程式。每次複製一個位元組，資料移動和迴圈邏輯採用 16 位操作。

上面的程式碼使用 BP（基指標）暫存器建立一個呼叫幀（包含子程式執行過程中的所有引數和區域性變數的棧的區域）。這種呼叫約定支援可重入和遞迴程式碼，大多數類 ALGOL 語言上世紀 50 年代後期就已採用這種約定。ES 段暫存器儲存在堆疊上，並用 DS 段暫存器中的值替換，於是指令會在相同的源資料段和目的資料段之間操作。在返回前，子程式恢復了 ES 暫存器以前的值。

上面的子程式是一種比較麻煩的複製成塊資料的方法。若源資料區域和目的資料區域都是處於單個 65,536 位元組的段中（上述程式的要求），使用 8086 的塊 MOV 指令更有優勢。上面的迴圈部分可以替換為：

這種方法每次可以複製一個字。REP 指令使下面的 MOVSW 重複直至 CX=0，重複之時自動遞增 SI 和 DI。另外，MOVSB 或 MOVSD 指令可以用來一次複製單個位元組或雙字。大多數彙編器在 REP 指令用在 MOVSW 之前為 REP MOVSW 的情況下都會正確彙編。

如果被中斷，這個程式也能正確執行，因為程式計數器會繼續指向 REP 指令，知道塊複製已經結束。複製會在中斷服務程式將控制恢復的時候繼續。

2.6 效能

外部匯流排作為資料與地址的複用，降低了 CPU 的效能。取 16 位元或 8 位元資料需要 4 個時鐘週期。指令的長度為 1-6 個位元組，取指令與執行是併發完成的。CPU 內的匯流排介面單元把取到的指令儲存在 6 位元組的預取佇列中。

EA = 計算有效地址的時間，5 到 12 週期.

用時為最好的情形，依賴於預取狀態，指令對齊，及其它因素.

8086 涉及記憶體訪問的指令，包括跳轉（jump）指令需要比 8080 與 8085 更多的時間，原因在於：

取指令與執行指令是鬆散耦合，對於跳轉與隨機資料訪問沒有特殊措施，效率較低.

沒有專門的地址計算部件，只能用主 ALU，雖然有專用的段地址 + 偏移地址的加法器
外部地址匯流排與資料匯流排是多工複用，與 8 位處理器相比要多用 33~50% 的匯流排週期

8086 的後繼處理器的記憶體訪問效能大大增強了。80186 與 80286 有專門的地址計算硬體，節約了很多時間週期。80286 的外部地址匯流排與資料匯流排是分開各自專用的。

2.7 浮點

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/）是連載高電壓還是接地決定了模式。改變引腳 #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 個。