組合語言是與 CPU 指令集一一對應的低級語言,學習它必須理解處理器微架構:寄存器組、記憶體分段機制、標誌寄存器條件判斷、I/O 端口通訊。本文針對 Intel x86 及相容處理器(IA-32),系統梳理這些核心概念,為後續指令集學習打下堅實基礎。
8 個 32 位通用寄存器,各有專長:
| 寄存器 | 全稱 | 主要用途 | 子寄存器 |
|---|---|---|---|
| EAX | Accumulator(累加器) | 算術/邏輯運算隱含目的操作數、函數返回值、乘除法被乘數/被除數 | AX (16位), AL/AH (8位) |
| EBX | Base Register(基址寄存器) | 記憶體定址基址、指向資料結構 | BX, BL/BH |
| ECX | Counter Register(計數器) | 迴圈計數 (LOOP)、字串操作重複前綴 (REP) 計數 | CX, CL/CH |
| EDX | Data Register(資料寄存器) | 乘法高位結果、除法餘數、I/O 端口地址 | DX, DL/DH |
| ESI | Source Index(源索引) | 字串操作源地址 (DS:ESI) | SI |
| EDI | Destination Index(目標索引) | 字串操作目標地址 (ES:EDI) | DI |
| EBP | Base Pointer(基址指標) | 堆疊框架指標,訪問區域變數/參數 (EBP+/-offset) | BP |
| ESP | Stack Pointer(堆疊指標) | 指向當前棧頂,PUSH/POP/CALL/RET 隱含使用,**極少作其他用途** | SP |
push ebp ; 保存調用者 EBP mov ebp, esp ; 建立新框架基址 sub esp, xxx ; 分配區域變數空間 ... ; 函數體 mov esp, ebp ; 恢復棧指標 pop ebp ; 恢復調用者 EBP ret ; 返回
x86 實模式/保護模式均使用段式定址:邏輯地址 = 段選擇子:偏移量。六個段寄存器:
| 段寄存器 | 全稱 | 用途 |
|---|---|---|
| CS | Code Segment | 指向當前執行代碼段。CS:EIP 指向下一條指令。只能透過控制轉移指令 (JMP, CALL, RET, Jcc) 修改,不可直接 MOV CS, ...。 |
| DS | Data Segment | 預設資料段,大多數記憶體存取 (MOV EAX, [address]) 隱含使用 DS。 |
| ES | Extra Segment | 額外資料段,字串操作目標 (ES:EDI) 隱含使用。 |
| FS | Extra Segment 2 | 額外資料段,Win32 用於 TLS (Thread Local Storage) 指標。 |
| GS | Extra Segment 3 | 額外資料段,Linux 內核用於 per-CPU 變數。 |
| SS | Stack Segment | 堆疊段,SS:ESP 指向棧頂。所有棧操作隱含使用 SS。 |
關鍵點:代碼與資料在物理上均為二進制位元組,區別僅在於「如何被解釋」。同一物理記憶體區域可同時擁有代碼段描述符 (CS) 與資料段描述符 (DS) —— 自修改代碼即利用此特性。
32 位狀態/控制標誌組合,常用條件標誌:
| 符號 | 全稱 | 置位條件 |
|---|---|---|
| CF | Carry Flag (進位/借位) | 無符號運算產生進位 (加法) 或借位 (減法) |
| ZF | Zero Flag (零標誌) | 運算結果為 0 |
| SF | Sign Flag (符號標誌) | 運算結果最高位為 1 (負數) |
| OF | Overflow Flag (溢出標誌) | 帶符號運算結果超出可表示範圍 |
Jcc 根據標誌組合決定是否跳轉,分無符號與帶符號兩組:
| 無符號比較 | 帶符號比較 | 含義 |
|---|---|---|
| JA / JNBE | JG / JNLE | 大於 (Above / Greater) |
| JAE / JNB | JGE / JNL | 大於等於 |
| JB / JNAE | JL / JNGE | 小於 |
| JBE / JNA | JLE / JNG | 小於等於 |
| JE / JZ | JE / JZ | 等於 (ZF=1) |
| JNE / JNZ | JNE / JNZ | 不等於 (ZF=0) |
| JC | JO | 進位/溢出 |
| JNC | JNO | 無進位/無溢出 |
| - | JS / JNS | 負數/非負數 (SF) |
記憶口訣:A=Above, B=Below, C=Carry, G=Greater, L=Less, O=Overflow, S=Sign, E=Equal, N=Not, Z=Zero。無符號用 A/B,帶符號用 G/L。
IN AL/AX/EAX, DX (讀)、OUT DX, AL/AX/EAX (寫)、INS/OUTS (串列傳輸)。掌握寄存器專長、分段定址、標誌條件跳轉、端口 I/O 這四大支柱,即擁有了閱讀、編寫、除錯 x86 組合語言的「地圖與指南針」。下一步建議學習:資料傳送指令、算術邏輯指令、控制轉移指令、字串操作指令、系統指令 (LGDT, LIDT, MOV CR0 等)。