8086/88 採用分段式記憶體架構,物理位址 = 段基址 × 16 + 偏移位址 (即 段基址 << 4 + 偏移)。理解五種基本定址模式,是撰寫高效組語、分析程式碼、除錯的基礎。本文以「大樓-單元-門牌」比喻直觀解釋,並提供 DEBUG 實際輸出與完整程式範例驗證。
DEBUG D 命令輸出範例:
0B1F:0100 00 80 FF 02 75 05 C6 46-00 00 C3 E8 8C EB B4 3B
↑ ↑
單元 0100h 門牌 0~F (16 字節/行)
概念:已站在門口,直接敲門進入。操作數在指令中直接給出位移量,預設段為 DS。
MOV AX, [2000H] ; 讀取 DS:2000h 字組
MOV AX, 2000H ; 立即數載入 AX,非記憶體存取
物理位址 = DS × 16 + 2000h
概念:站在單元門口,知道目標在該單元的第幾樓 (暫存器值)。使用 BX、SI、DI、BP 存放偏移量。
MOV AX, [BX] ; DS:BX
MOV AX, [SI] ; DS:SI
MOV AX, [DI] ; DS:DI
MOV AX, [BP] ; SS:BP (預設段為 SS)
物理位址 = DS × 16 + BX (或 SI/DI) / SS × 16 + BP
概念:目標在你家樓上/樓下幾層 (位移量 + 暫存器)。
MOV AX, COUNT[SI] ; 等價於 [COUNT + SI]
MOV AX, [COUNT + SI] ; COUNT 為位移常數
物理位址 = DS × 16 + SI + 位移量 (8/16-bit 位移) / SS × 16 + BP + 位移量
概念:同棟大樓不同單元,需知道單元號 (BX/BP) 與樓層 (SI/DI)。
MOV AX, [BX][DI] ; 等價於 [BX + DI]
MOV AX, [BP][SI] ; SS:BP+SI
物理位址 = DS × 16 + BX + SI/DI / SS × 16 + BP + SI/DI
概念:結合位移量 + 基址暫存器 + 變址暫存器,最靈活的定址方式。
MOV AX, MASK[BX][SI] ; 等價於 [MASK + BX + SI]
MOV AX, [MASK + BX + SI]
物理位址 = DS × 16 + BX + SI/DI + 位移量 / SS × 16 + BP + SI/DI + 位移量
| 模式 | 指令範例 | 預設段 | 物理位址計算 | 可用暫存器組合 |
|---|---|---|---|---|
| 直接 | MOV AX, [2000H] | DS | DS×16 + 2000H | 無 |
| 間接 | MOV AX, [BX] | DS | DS×16 + BX | BX, SI, DI |
| 間接 | MOV AX, [BP] | SS | SS×16 + BP | BP |
| 相對 | MOV AX, 10H[SI] | DS | DS×16 + SI + 10H | BX, SI, DI, BP |
| 基址變址 | MOV AX, [BX][DI] | DS | DS×16 + BX + DI | BX/BP + SI/DI |
| 相對基址變址 | MOV AX, TABLE[BX][SI] | DS | DS×16 + BX + SI + TABLE | BX/BP + SI/DI + 位移 |
功能:輸入字串 (最多 9 字元),按 Enter 後倒序顯示。展示 暫存器間接定址 存取緩衝區長度與字元。
data segment
user_string db 10, 0, 10 dup(?) ; DOS 緩衝區格式:最大長度、實際長度、資料區
data ends
code segment
assume cs:code, ds:data
start:
mov ax, data
mov ds, ax
lea dx, user_string ; DX = 緩衝區位移
mov ah, 0Ah ; DOS 0Ah: 帶回顯的字串輸入
int 21h
xor si, si
xor bx, bx
mov bx, dx ; BX = 緩衝區基址
mov cx, [bx + si + 1] ; 間接定址讀取「實際長度」 (Offset 1)
xor ch, ch ; 清高位,CX = 長度
mov di, cx ; DI = 索引,指向最後一字元
lop:
mov ah, 2 ; DOS 2h: 顯示字元 (DL)
mov dx, [bx + di + 1] ; 間接定址讀取字元 (資料區起始 Offset 2,故 +1)
int 21h
dec di
loop lop ; CX 遞減至 0 結束
mov ah, 4Ch
int 21h
code ends
end start
MOV CX, [BX + SI + 1]:BX 基址 (緩衝區開頭),SI=0,位移 1 → 讀取「實際輸入長度」位元組。MOV DX, [BX + DI + 1]:DI 從長度-1 遞減至 0,位移 1 (跳過長度位元組) → 依序讀取最後一字元至第一字元。LOOP LOP:CX 為計數器,自動 DEC CX / JNZ,極適合已知次數迴圈。.EXE,用 DEBUG PROG.EXE 載入。R 檢視暫存器,U 反組譯確認指令編碼。G 執行,輸入測試字串觀察輸出。D DS:OFFSET 檢視緩衝區內容結構 (長度位元組、資料區)。掌握五種定址模式的物理位址計算、預設段暫存器、指令編碼差異,能讓您:
建議配合 DEBUG 實機操作,觀察暫存器與記憶體變化,建立直觀的分段定址心智模型。