以下是 **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 中斷)** 顯示每次結果,也可以提供範例哦。你想要完整輸出九九乘法表的版本嗎?