以下是 **8086 指令集** 的完整分類清單,並附上一些簡單實例**。
---
## 🧠 一、資料傳送類(Data Transfer Instructions)
用來搬運資料,像在「搬家」一樣把東西從一個地方移到另一個地方。
| 指令 | 說明 | 範例 | 意義(白話) |
|------|------|------|--------------|
| `MOV` | 資料搬運 | `MOV AX, 5` | 把數字 5 放進 AX(想像成變數)|
| `XCHG` | 資料交換 | `XCHG AX, BX` | 把 AX 和 BX 裡的東西交換 |
| `IN` | 從外部裝置讀資料 | `IN AL, 60h` | 從鍵盤(60h)讀資料進 AL |
| `OUT` | 將資料送到外部裝置 | `OUT 60h, AL` | 把 AL 裡的資料送到鍵盤控制器 |
| `LEA` | 載入有效位址 | `LEA SI, [BX+5]` | 把位址算出來給 SI |
| `LDS`, `LES` | 載入指標與段位址 | `LDS SI, [2000]` | 把記憶體位址 2000 裡的資料載入 |
---
## 🧮 二、算術類(Arithmetic Instructions)
用來做加減乘除等數學運算。
| 指令 | 說明 | 範例 | 意義(白話) |
|------|------|------|--------------|
| `ADD` | 加法 | `ADD AX, BX` | AX = AX + BX |
| `SUB` | 減法 | `SUB AX, 1` | AX = AX - 1 |
| `MUL` | 無號乘法 | `MUL BL` | AX = AL × BL |
| `IMUL` | 有號乘法 | `IMUL BL` | AX = AL × BL(有正負)|
| `DIV` | 無號除法 | `DIV BL` | AL = AX ÷ BL |
| `IDIV` | 有號除法 | `IDIV BL` | 有正負的除法 |
| `INC` | 加一 | `INC CX` | CX = CX + 1 |
| `DEC` | 減一 | `DEC DX` | DX = DX - 1 |
| `NEG` | 取負值 | `NEG AX` | AX = -AX |
| `CMP` | 比較 | `CMP AX, 10` | 比 AX 和 10 誰大 |
---
## 🔍 三、邏輯與位元運算(Logic & Bit Instructions)
| 指令 | 說明 | 範例 | 白話意思 |
|------|------|------|----------|
| `AND` | 位元與 | `AND AL, 0Fh` | 清除高 4 位 |
| `OR` | 位元或 | `OR AL, 0F0h` | 設定高 4 位 |
| `XOR` | 位元互斥或 | `XOR AL, AL` | 把 AL 清零 |
| `NOT` | 反轉位元 | `NOT AL` | 0 變 1,1 變 0 |
| `SHL`, `SAL` | 左移 | `SHL AL, 1` | 乘 2 |
| `SHR` | 右移 | `SHR AL, 1` | 除 2 |
| `SAR` | 有號右移 | `SAR AL, 1` | 除 2,保留符號 |
| `TEST` | 測試 | `TEST AL, 01h` | 看 AL 的第 0 位是不是 1 |
---
## 🔁 四、控制流程(跳躍、呼叫)
| 指令 | 說明 | 範例 | 白話意思 |
|------|------|------|----------|
| `JMP` | 無條件跳躍 | `JMP START` | 跳到 START |
| `JE`, `JZ` | 相等就跳 | `JE DONE` | 如果相等就跳 DONE |
| `JNE`, `JNZ` | 不等就跳 | `JNE AGAIN` | 如果不相等就跳 AGAIN |
| `JC` | 進位就跳 | `JC CARRY` | 有進位就跳 |
| `CALL` | 呼叫副程式 | `CALL PRINT` | 跳去執行 PRINT |
| `RET` | 回主程式 | `RET` | 結束副程式 |
| `LOOP` | 重複執行 | `LOOP AGAIN` | CX 不為 0 就跳回 AGAIN |
---
## 🧹 五、字串處理指令(簡化版)
| 指令 | 說明 |
|------|------|
| `MOVSB` | 將字串中一個 byte 複製到目的地 |
| `CMPSB` | 比較兩個字串的 byte |
| `SCASB` | 搜尋指定的 byte 值 |
| `LODSB` | 載入來源 byte 到 AL |
| `STOSB` | 將 AL 儲存到目的地 |
---
## 🔧 六、旗標控制指令
| 指令 | 說明 |
|------|------|
| `CLC` | 清除進位旗標 |
| `STC` | 設定進位旗標 |
| `CLD` | 清除方向旗標 |
| `STD` | 設定方向旗標 |
| `CMC` | 反轉進位旗標 |
---
## 🔁 七、迴圈與重複指令(Loop / Repeat)
| 指令 | 說明 |
|------|------|
| `REP` | 重複執行(通常搭配字串指令) |
| `REPE` / `REPZ` | 值相等就重複 |
| `REPNE` / `REPNZ` | 值不等就重複 |
---
## 🧩 八、中斷指令
| 指令 | 說明 |
|------|------|
| `INT` | 發出中斷要求(如 `INT 21h`)|
| `IRET` | 從中斷返回 |
---
## ✅ 小實例(簡單程式)
### 範例一:加法 + 顯示
```asm
MOV AX, 5 ; AX = 5
MOV BX, 3 ; BX = 3
ADD AX, BX ; AX = AX + BX = 8
```
👉 想像成:
```text
你有兩個盒子(AX 和 BX),放了 5 和 3,然後把兩個數字加在一起放回 AX。
```
---
### 範例二:迴圈從 5 數到 1
```asm
MOV CX, 5 ; 設定計數器 5 次
AGAIN:
DEC CX ; 減一
JNZ AGAIN ; 如果不是零就繼續
```
👉 像在玩「倒數計時」:
```text
從 5 數到 1,每次減一,數完就結束。
```
---
以下是針對 **8086 組合語言** 所寫的簡單範例程式,分別實作 **加法機、乘法機、倒數計時器、九九乘法表**。
---
## 🧮 1. 加法機(兩數相加)
```asm
MOV AX, 4 ; 把 4 放到 AX
MOV BX, 5 ; 把 5 放到 BX
ADD AX, BX ; 把 AX 和 BX 相加,結果放回 AX
; AX 現在是 9(4+5)
```
🔎 白話:像兩個杯子裝了 4 和 5,把它們倒到一個大碗裡,加起來變 9。
---
## ✖️ 2. 乘法機(兩數相乘)
```asm
MOV AL, 6 ; AL 放 6
MOV BL, 7 ; BL 放 7
MUL BL ; AX = AL × BL
; 結果存在 AX 中,6 × 7 = 42(2Ah)
```
🔎 白話:你拿 6 顆糖果,做 7 次,一共就有 42 顆糖果。
---
## ⏳ 3. 倒數計時器(從 5 數到 1)
```asm
MOV CX, 5 ; 設定計數器為 5
COUNTDOWN:
; 想像這裡有顯示數字 CX 的功能
DEC CX ; CX = CX - 1
JNZ COUNTDOWN ; CX ≠ 0 就繼續
```
🔎 白話:像在體育課倒數計時「5、4、3、2、1」,每次減一,直到變成 0 停止。
---
## 🧮 4. 九九乘法表(1×1 到 9×9)
```asm
MOV DL, 1 ; 外層乘數 i = 1
OUTER_LOOP:
MOV DH, 1 ; 內層乘數 j = 1
INNER_LOOP:
MOV AL, DL ; AL = i
MUL DH ; AX = AL × DH(i × j)
; 這裡 AX 是乘積結果,可顯示 (i × j = AX)
; 顯示功能略過,可用中斷 INT 21h 顯示(進階)
INC DH ; j = j + 1
CMP DH, 10 ; 如果 j = 10,就結束內層
JL INNER_LOOP ; 如果 j < 10,繼續內層迴圈
INC DL ; i = i + 1
CMP DL, 10 ; 如果 i = 10,就結束外層
JL OUTER_LOOP ; 如果 i < 10,繼續外層迴圈
```
🔎 白話:像兩層 for 迴圈跑九九乘法表,用 DL 表示第幾列,用 DH 表示第幾欄。
---
如果你希望我幫你加上 **螢幕輸出功能(透過 DOS 中斷)** 顯示每次結果,也可以提供範例哦。你想要完整輸出九九乘法表的版本嗎?