Intel 8080

英特爾8080微處理器是英特爾設計和製造的第二款8位微處理器。它於1974年4月首次亮相，是早期8008設計的擴展和增強版本，儘管它們之間沒有二進位兼容性。最初規定的時鐘頻率或頻率限制為2 MHz，常見指令使用4、5、7、10或11個周期。因此，該處理器能夠每秒執行數十萬條指令。後來推出了兩個更快的變種，8080A-1和8080A-2，它們的時鐘頻率限制分別為3.125 MHz和2.63 MHz。8080在大多數應用中需要兩個支持晶片才能工作：i8224時鐘生成器/驅動器和i8228總線控制器。它採用N型金屬氧化物半導體邏輯（NMOS）實現，使用非飽和增強模式電晶體作為負載，因此除了主要的電晶體-電晶體邏輯（TTL）兼容的+5 V外，還需要+12 V和-5 V的電壓。

儘管早期的微處理器通常用於如計算器、收銀機、電腦終端、工業機器人等大批量生產的設備中，8080在更廣泛的應用中取得了更大的成功，它在很大程度上被認為是微型計算機行業的起點。其受歡迎的幾個因素包括：其40腳封裝比18腳的8008更易於接口，並且使其數據總線更高效；其NMOS實現使其電晶體比P型金屬氧化物半導體邏輯（PMOS）的8008更快，同時通過使其與TTL兼容簡化了接口；可用的支持晶片種類更多；其指令集相對於8008有所增強；以及其完整的16位地址總線（相對於8008的14位）使其能夠訪問64 KB的記憶體，是8008範圍的四倍。它被用於Altair 8800和後續的S-100總線個人電腦，直到被Z80取代，並且是由Gary Kildall開發的CP/M作業系統的原始目標CPU。

8080直接影響了後來的x86架構。英特爾設計了8086，使其彙編語言與8080足夠相似，大多數指令可以直接映射到彼此上，這樣就可以在8086上執行轉譯的8080彙編代碼。

## 歷史

微處理器的客戶對採用8008持謹慎態度，原因在於它存在諸多限制，如單一尋址模式、低時鐘速度、低引腳數以及小型片上棧，這些因素限制了軟體的規模和複雜度。對於8080的設計提案有很多，範圍從僅僅給8008添加棧指令到完全脫離所有之前英特爾的架構。最終的設計是各種提案之間的一種妥協。

Federico Faggin是8080架構的發起人，他在1972年初向英特爾的管理層提出了這一晶片設計，並推動了它的實施。六個月後，他終於獲得了開發的許可。Faggin於1972年11月從日本聘請了與他一起設計4004的Masatoshi Shima。Shima在Faggin的指導下進行了詳細設計，使用了Faggin為4000系列創造的隨機邏輯矽門設計方法。

8080被明確設計為一個面向更廣泛客戶的通用微處理器。大量的開發工作致力於嘗試將8008的輔助晶片的功能整合到一個封裝中。開發初期就決定8080不與8008二進位兼容，而是選擇源兼容性，一旦通過轉譯器運行，就可以允許新軟體不受8008同樣的限制。出於同樣的原因，以及為了擴展基於棧的例程和中斷的能力，棧被移至外部記憶體。

注意到程式設計師在大型機系統中對通用寄存器的專用使用，晶片架構師Stanley Mazor決定8080的寄存器將是專用的，寄存器對有不同的用途集。這也使得工程師能夠更有效地將電晶體用於其他目的。

Shima在1973年8月完成了布局。在NMOS製造調整之後，一個8080的原型在1974年1月完成。它有一個缺陷，即使用標準TTL設備驅動時，因為高電流流入狹窄的線路而增加了地線電壓。在Shima對原型進行特性分析之前，英特爾已經按照銷售部門的指示生產了40,000個8080單元。它被發布時要求使用低功耗肖特基TTL（LS TTL）設備。8080A修正了這個缺陷。

## 功能

### 編譯模型

Intel 8080 是 8008 的後繼者。它使用與 8008 相同的基本指令集和寄存器模型，儘管它既不與其前身兼容原始碼，也不兼容二進位代碼。8008 中的每條指令在 8080 中都有等效指令。8080 還在其指令集中添加了 16 位操作。而 8008 需要使用 HL 寄存器對來間接訪問其 14 位記憶體空間，8080 添加了尋址模式，允許直接訪問其完整的 16 位記憶體空間。8008 的內部 7 級下壓調用堆棧被專用的 16 位堆棧指針（SP）寄存器替換。8080 的 40 引腳 DIP 封裝允許它提供 16 位地址總線和 8 位數據總線，實現對 64 KiB（2^16 字節）記憶體的訪問。

15｜14｜13｜12｜11｜10｜09｜08｜07｜06｜05｜04｜03｜02｜01｜00｜(bit position)

主寄存器

A｜Flags｜程序狀態字

B｜C｜B

D｜E｜D

H｜L｜H (間接地址)

索引寄存器

SP｜棧指針

程序計數器

PC｜程序計數器

狀態寄存器

S｜Z｜0｜AC｜0｜P｜1｜C｜Flags

### 寄存器

處理器有七個 8 位寄存器（A、B、C、D、E、H 和 L），其中 A 是主 8 位累加器。其他六個寄存器可以根據特定指令作為單獨的 8 位寄存器或在三個 16 位寄存器對（BC、DE 和 HL，在 Intel 文檔中分別稱為 B、D 和 H）中使用。某些指令還允許 HL 寄存器對作為（有限的）16 位累加器使用。偽寄存器 M，指的是由 HL 指向的解引用記憶體位置，幾乎可以在任何其他寄存器可以使用的地方使用。8080 有一個 16 位的堆棧指針指向記憶體，替換了 8008 的內部堆棧，並有一個 16 位的程序計數器。

標誌

處理器維護內部標誌位（狀態寄存器），這些標誌位指示算術和邏輯指令的結果。只有特定的指令會影響標誌位。標誌位包括：

- 符號（S），如果結果為負則設置。
- 零（Z），如果結果為零則設置。
- 奇偶校驗（P），如果結果中 1 的位數為偶數則設置。
- 進位（C），如果最後一次加法操作產生了進位或者最後一次減法操作需要借位則設置。
- 輔助進位（AC 或 H），用於二進位編碼的十進位算術（BCD）。

特定指令可以設置或反轉進位位。條件分支指令測試各種標誌狀態位。累加器和標誌位一起被稱為 PSW，或程序狀態字。PSW 可以被推入或從堆棧中彈出。

### 命令與指令

與許多其他 8 位處理器一樣，所有指令都編碼為一個字節（包括寄存器編號，但不包括立即數數據），以簡化操作。有些可以跟隨一到兩個字節的數據，這可以是立即數操作數、記憶體地址或埠號。像更高級的處理器一樣，它有自動 CALL 和 RET 指令用於多級過程調用和返回（甚至可以像跳轉一樣有條件地執行），以及用於在機器堆棧上保存和恢復任何 16 位寄存器對的指令。存在八個一字節的調用指令（RST），用於在固定地址 00h、08h、10h、...、38h 處的子程序。這些旨在由外部硬體提供，以調用相應的中斷服務例程，但也經常用作快速系統調用。執行最慢的指令是 XTHL，用於將 HL 寄存器對與堆棧指針指示的地址處存儲的值交換。

#### 8 位指令

所有具有兩個操作數的 8 位操作只能在 8 位累加器（A 寄存器）上執行。另一個操作數可以是立即值、另一個 8 位寄存器或由 16 位寄存器對 HL 地址的記憶體字節。增量和減量操作可以在任何 8 位寄存器或 HL 地址的記憶體字節上執行。支持直接複製任意兩個 8 位寄存器之間以及任何 8 位寄存器和 HL 地址的記憶體字節之間。由於 MOV 指令的規則編碼（使用了可用操作碼空間的四分之一），存在將寄存器複製到其自身的冗餘代碼（MOV B,B），除了用於延遲外幾乎無用。然而，系統性的 MOV M,M 操作碼被用來編碼停止（HLT）指令，直到外部重置或中斷發生時停止執行。

#### 16 位操作

雖然 8080 通常是一個 8 位處理器，它有限地能夠執行 16 位操作。任何三個 16 位寄存器對（BC、DE 或 HL，在 Intel 文檔中分別稱為 B、D、H）或 SP 可以使用LXI加載立即 16 位值，使用INX 和 DCX進行增量或減量操作，或使用 DAD 加到 HL 上。通過將 HL 加到其自身，可以使用一條指令實現與 16 位算術左移相同的結果。唯一影響任何標誌的 16 位指令是 DAD，它設置 CY（進位）標誌，以允許進行編程的 24 位或 32 位算術（或更大），這對於實現浮點算術是必需的。可以使用 DAD SP 和 SPHL 分配堆棧幀。可以使用 PCHL, 執行對計算指針的跳轉。LHLD 從直接尋址的記憶體中加載 HL，SHLD 同樣存儲 HL。XCHG指令交換 HL 和 DE 寄存器對的值。XTHL 與堆棧上最後推入的項和 HL 交換。

### 指令集

操作碼｜操作數｜助記符｜周期數｜描述

7｜6｜5｜4｜3｜2｜1｜0｜b2｜b3

0｜0｜0｜0｜0｜0｜0｜0｜—｜—｜NOP｜4｜No operation

0｜0｜RP｜0｜0｜0｜1｜datlo｜dathi｜LXI rp,data｜10｜RP ← data

0｜0｜RP｜0｜0｜1｜0｜—｜—｜STAX rp｜7｜(RP) ← A BC or DE only

0｜0｜RP｜0｜0｜1｜1｜—｜—｜INX rp｜5｜RP ← RP + 1

0｜0｜DDD｜1｜0｜0｜—｜—｜INR ddd｜5/10｜DDD ← DDD + 1

0｜0｜DDD｜1｜0｜1｜—｜—｜DCR ddd｜5/10｜DDD ← DDD - 1

0｜0｜DDD｜1｜1｜0｜data｜—｜MVI ddd,data｜7/10｜DDD ← data

0｜0｜RP｜1｜0｜0｜1｜—｜—｜DAD rp｜10｜HL ← HL + RP

0｜0｜RP｜1｜0｜1｜0｜—｜—｜LDAX rp｜7｜A ← (RP) BC or DE only

0｜0｜RP｜1｜0｜1｜1｜—｜—｜DCX rp｜5｜RP ← RP - 1

0｜0｜0｜0｜0｜1｜1｜1｜—｜—｜RLC｜4｜A1-7 ← A0-6; A0 ← Cy ← A7

0｜0｜0｜0｜1｜1｜1｜1｜—｜—｜RRC｜4｜A0-6 ← A1-7; A7 ← Cy ← A0

0｜0｜0｜1｜0｜1｜1｜1｜—｜—｜RAL｜4｜A1-7 ← A0-6; Cy ← A7; A0 ← Cy

0｜0｜0｜1｜1｜1｜1｜1｜—｜—｜RAR｜4｜A0-6 ← A1-7; Cy ← A0; A7 ← Cy

0｜0｜1｜0｜0｜0｜1｜0｜addlo｜addhi｜SHLD add｜16｜(add) ← HL

0｜0｜1｜0｜0｜1｜1｜1｜—｜—｜DAA｜4｜If A0-3 > 9 OR AC = 1 then A ← A + 6; then if A4-7 > 9 OR Cy = 1 then A ← A + 0x60

0｜0｜1｜0｜1｜0｜1｜0｜addlo｜addhi｜LHLD add｜16｜HL ← (add)

0｜0｜1｜0｜1｜1｜1｜1｜—｜—｜CMA｜4｜A ← ¬A

0｜0｜1｜1｜0｜0｜1｜0｜addlo｜addhi｜STA add｜13｜(add) ← A

0｜0｜1｜1｜0｜1｜1｜1｜—｜—｜STC｜4｜Cy ← 1

0｜0｜1｜1｜1｜0｜1｜0｜addlo｜addhi｜LDA add｜13｜A ← (add)

0｜0｜1｜1｜1｜1｜1｜1｜—｜—｜CMC｜4｜Cy ← ¬Cy

0｜1｜DDD｜SSS｜—｜—｜MOV ddd,sss｜5/7｜DDD ← SSS

0｜1｜1｜1｜0｜1｜1｜0｜—｜—｜HLT｜7｜Halt

1｜0｜ALU｜SSS｜—｜—｜ADD ADC SUB SBB ANA XRA ORA CMP sss｜4/7｜A ← A ALU operation SSS

1｜1｜CC｜0｜0｜0｜—｜—｜Rcc｜5/11｜If cc true, PC ← (SP), SP ← SP + 2

1｜1｜RP｜0｜0｜0｜1｜—｜—｜POP rp｜10｜RP ← (SP), SP ← SP + 2

1｜1｜CC｜0｜1｜0｜addlo｜addhi｜Jcc add｜10｜If cc true, PC ← add

1｜1｜0｜0｜0｜0｜1｜1｜addlo｜addhi｜JMP add｜10｜PC ← add

1｜1｜CC｜1｜0｜0｜addlo｜addhi｜Ccc add｜11/17｜If cc true, SP ← SP - 2, (SP) ← PC, PC ← add

1｜1｜RP｜0｜1｜0｜1｜—｜—｜PUSH rp｜11｜SP ← SP - 2, (SP) ← RP

1｜1｜ALU｜1｜1｜0｜data｜—｜ADI ACI SUI SBI ANI XRI ORI CPI data｜7｜A ← A ALU operation data

1｜1｜N｜1｜1｜1｜—｜—｜RST n｜11｜SP ← SP - 2, (SP) ← PC, PC ← N x 8

1｜1｜0｜0｜1｜0｜0｜1｜—｜—｜RET｜10｜PC ← (SP), SP ← SP + 2

1｜1｜0｜0｜1｜1｜0｜1｜addlo｜addhi｜CALL add｜17｜SP ← SP - 2, (SP) ← PC, PC ← add

1｜1｜0｜1｜0｜0｜1｜1｜port｜—｜OUT port｜10｜Port ← A

1｜1｜0｜1｜1｜0｜1｜1｜port｜—｜IN port｜10｜A ← Port

1｜1｜1｜0｜0｜0｜1｜1｜—｜—｜XTHL｜18｜HL ↔ (SP)

1｜1｜1｜0｜1｜0｜0｜1｜—｜—｜PCHL｜5｜PC ← HL

1｜1｜1｜0｜1｜0｜1｜1｜—｜—｜XCHG｜4｜HL ↔ DE

1｜1｜1｜1｜0｜0｜1｜1｜—｜—｜DI｜4｜Disable interrupts

1｜1｜1｜1｜1｜0｜0｜1｜—｜—｜SPHL｜5｜SP ← HL

1｜1｜1｜1｜1｜0｜1｜1｜—｜—｜EI｜4｜Enable interrupts

7｜6｜5｜4｜3｜2｜1｜0｜b2｜b3｜助記符｜周期數｜描述

SSS DDD｜2｜1｜0｜CC｜ALU｜RP

B｜0｜0｜0｜NZ｜ADD ADI (A ← A + arg)｜BC

C｜0｜0｜1｜Z｜ADC ACI (A ← A + arg + Cy)｜DE

D｜0｜1｜0｜NC｜SUB SUI (A ← A - arg)｜HL

E｜0｜1｜1｜C｜SBB SBI (A ← A - arg - Cy)｜SP or PSW

H｜1｜0｜0｜PO｜ANA ANI (A ← A ∧ arg)

L｜1｜0｜1｜PE｜XRA XRI (A ← A ⊻ arg)

M｜1｜1｜0｜P｜ORA ORI (A ← A ∨ arg)

A｜1｜1｜1｜N｜CMP CPI (A - arg)

SSS DDD｜2｜1｜0｜CC｜ALU

### 輸入/輸出方案

#### 輸入輸出埠空間

8080 支持多達 256 個輸入/輸出（I/O）埠，通過使用埠地址作為操作數的專用 I/O 指令訪問。這種 I/O 映射方案被認為是一個優勢，因為它釋放了處理器有限的地址空間。許多 CPU 架構相反使用所謂的記憶體映射 I/O（MMIO），在這種設計中，RAM 和外圍晶片使用共同的地址空間。這消除了對專用 I/O 指令的需求，儘管這樣的設計可能存在的一個缺點是，由於外圍設備通常比記憶體慢，因此必須使用特殊硬體來插入等待狀態。然而，在一些簡單的 8080 電腦中，I/O 確實被當作記憶體單元進行尋址，即「記憶體映射」，從而不使用 I/O 命令。I/O 尋址有時也可以利用處理器將相同的 8 位埠地址輸出到低地址字節和高地址字節的事實（即，IN 05h 會在 16 位地址總線上放置地址 0505h）。類似的 I/O 埠方案被用在向後兼容的 Zilog Z80 和 Intel 8085，以及密切相關的 x86 微處理器系列中。

#### 獨立的堆棧空間

處理器狀態字中的一個位（見下文）指示處理器正在從堆棧訪問數據。使用這個信號，可以實現一個獨立的堆棧記憶體空間。這個功能很少被使用。

### 狀態字

對於更高級的系統，在每個機器周期的開始，處理器在數據總線上放置一個八位狀態字。這個字節包含的標誌決定了是訪問記憶體還是 I/O 埠，以及是否需要處理中斷。

中斷系統狀態（啟用或禁用）也在一個單獨的引腳上輸出。對於簡單系統，其中不使用中斷，在某些情況下可能會發現這個引腳被用作額外的單比特輸出埠（例如，在蘇聯製造的流行的 Radio-86RK 電腦）。

### 示例代碼

以下是8080/8085彙編器原始碼，用於一個名為memcpy的子程序，該子程序將給定大小的數據塊從一個位置複製到另一個位置。數據塊一次複製一個字節，數據移動和循環邏輯使用16位操作。

```











1000
1000
1000  78
1001  B1
1002  C8
1003  1A
1004  77
1005  13
1006  23
1007  0B
1008  78
1009  B1
100A  C2 03 10
100D  C9
```

```nasm
; memcpy --
; 将内存块从一个位置复制到另一个位置。
;
; 输入寄存器
;   BC - 要复制的字节数
;   DE - 源数据块的地址
;   HL - 目标数据块的地址
;
; 返回寄存器
;   BC - 零

            org     1000h       ;起始地址为1000h
memcpy      public
            mov     a,b         ;将寄存器B的值复制到寄存器A
            ora     c           ;寄存器A与寄存器C进行按位或操作，结果存入寄存器A
            rz                  ;如果零标志被置位，则返回
loop:       ldax    d           ;从DE指向的地址加载数据到A
            mov     m,a         ;将寄存器A的内容存储到HL指向的地址
            inx     d           ;增加 DE
            inx     h           ;增加 HL
            dcx     b           ;BC减一（不影响标志位）
            mov     a,b         ;将B复制到A（以便将BC与零比较）
            ora     c           ;A = A | C （B和C都是零吗？）
            jnz     loop        ;如果零标志未被置位，则跳转到'loop:'
            ret                 ;返回
```

### 針腳

地址總線擁有自己的16個針腳，而數據總線有8個可用的針腳，無需任何復用。使用另外兩個針腳（讀和寫信號），可以非常容易地組裝簡單的微處理器設備。僅需為獨立的IO空間、中斷和DMA添加解碼處理器針腳信號的晶片。

然而，針腳的負載能力是有限的；即使是簡單的電腦通常也需要總線放大器。

處理器需要三個電源（-5V、+5V和+12V）和兩個非重疊的高幅度同步信號。然而，至少在蘇聯後期的版本КР580ВМ80А能夠僅使用單一的+5V電源工作，將+12V針腳連接到+5V，將-5V針腳接地。

隨晶片提供的文檔中的針腳布局表，如下描述針腳：

針腳｜信號｜類型｜指令

1｜A10｜Output｜地址總線10

2｜GND｜地

3｜D4｜Bidirectional｜雙向數據總線，處理器還會暫時在此設置「處理器狀態」，提供有關處理器當前正在執行的操作的資訊：、D0 讀取中斷命令。響應中斷信號時，處理器正在讀取並執行一個帶有此標誌的任意命令。通常，支持晶片會提供子程序調用命令（CALL或RST），將控制權轉移到中斷處理代碼、D1 讀取（低電平意味著寫入）、D2 訪問堆棧（可能最初計劃了一個單獨的堆棧記憶體空間）、D3 無操作，已被HLT指令停止、D4 向輸出埠寫入數據、D5 讀取可執行指令的第一個字節、D6 從輸入埠讀取數據、D7 從記憶體讀取數據

4｜D5

5｜D6

6｜D7

7｜D3

8｜D2

9｜D1

10｜D0

11｜−5 V｜-5伏電源供應。這必須是首先連接的電源，並且是最後斷開的電源，否則處理器將會受損

12｜RESET｜Input｜復位。該信號強制執行位於0000地址的命令。其他處理器寄存器的內容不會被修改。這是一個反相輸入（激活電平為邏輯0）

13｜HOLD｜Input｜直接記憶體訪問請求。請求處理器將數據和地址總線切換到高阻抗（「斷開連接」）狀態

14｜INT｜Input｜中斷請求

15｜φ2｜Input｜時鐘發生器信號的第二相位

16｜INTE｜Output｜處理器擁有兩個命令，用於在該引腳上設置0或1電平。這個引腳通常被用於中斷控制。然而，在簡單的電腦中，它有時被用作單比特輸出埠，用於各種目的

17｜DBIN｜Output｜讀(處理器從記憶體或輸入埠讀取數據)

18｜WR｜Output｜寫(處理器向記憶體或輸出埠寫入數據。這是一個反向輸出，激活電平為邏輯零)

19｜SYNC｜Output｜激活電平表明處理器已經將「狀態字」放置在數據總線上。這個狀態字的各個位提供了額外的資訊，以支持獨立的地址和記憶體空間、中斷和直接記憶體訪問。這個信號在可以用於將數據總線上的處理器狀態字寫入某個外部寄存器之前，需要通過額外的邏輯處理，例如， 8238 系統控制器和總線驅動器

20｜+5 V｜+5伏電源供應

21｜HLDA｜Output｜直接記憶體訪問確認。處理器將數據和地址引腳切換到高阻抗狀態，允許其他設備操縱總線

22｜φ1｜Input｜時鐘發生器信號的第一相位

23｜READY｜Input｜等待(利用這個信號，可以暫停處理器的工作。它還用於支持基於硬體的逐步調試模式)

24｜WAIT｜Output｜等待(指示處理器處於等待狀態)

25｜A0｜Output｜地址總線

26｜A1

27｜A2

28｜12 V｜+12伏電源供應，這必須是最後連接和第一個斷開的電源

29｜A3｜Output｜地址總線；可以根據需求切換到高阻抗狀態

30｜A4

31｜A5

32｜A6

33｜A7

34｜A8

35｜A9

36｜A15

37｜A12

38｜A13

39｜A14

40｜A11

## 支持晶片

8080的成功關鍵因素之一是有廣泛的支持晶片可用，提供串行通信、計數/定時、輸入/輸出、直接記憶體訪問和可編程中斷控制等多種功能：

- 8214 - 優先級中斷控制單元
- 8224 – 時鐘發生器
- 8228/ 8238 – 系統控制器和總線驅動器
- 8251 – 通信控制器
- 8253 – 可編程間隔定時器
- 8255 – 可編程外圍接口
- 8257 – DMA控制器
- 8259 – 可編程中斷控制器

## 實現

8080積體電路使用非飽和增強型負載nMOS門，需要額外的電壓（用於負載門偏置）。它是在一個矽門過程中製造的，使用最小特徵尺寸為6微米。設計中大約4500個電晶體通過單層金屬層互聯，但較高電阻的多晶矽層（一些互聯需要更高的電壓）是用電晶體門實現的。晶片尺寸大約為20平方毫米。

## 基本資料

- 產品化：1974年
- 產品化：1990年
- CPU主頻範圍：2
- CPU主頻範圍：MHz
- CPU主頻範圍：3.125
- 製作工藝/製程：6 µm
- 推出公司：Intel
- 設計團隊：Intel
- manuf1：Intel
- sock1：DIP40
- pack1：40-pin DIP
- 指令集架構：8080
- transistors：4,500 or 6,000
- data-width：8 bits
- address-width：16 bits
- 核心數量：1
- 前任：Intel 8008
- 繼任：Intel 8085
- support status：Unsupported