GAS (GNU Assembler) 採用 AT&T 語法,每條指令以單字元尾碼標示操作數大小。本文整理資料型別對應尾碼、定址模式、資料傳送、算術邏輯、條件碼、比較/測試、條件設定/跳轉、函式呼叫等核心指令集,供 x86 組合語言開發參考。
操作數大小尾碼對照
| C 宣告 | GAS 尾碼 | 大小 (位元組) |
| char | b | 1 |
| short | w | 2 |
| (unsigned) int / long / char* | l | 4 |
| float | s | 4 |
| double | l | 8 |
| long double | t | 10/12 |
註:l 同時用於 4 位元組整數與 8 位元組雙精度浮點數,指令集不同故無歧義。
定址模式格式
| 格式 | 運算數值 | 名稱 | 範例 (GAS = C) |
| $Imm | Imm | 立即定址 | $1 = 1 |
| %Ea | R[Ea] | 暫存器定址 | %eax = eax |
| Imm | M[Imm] | 絕對定址 | 0x104 = *0x104 |
| (%Ea) | M[R[Ea]] | 間接定址 | (%eax) = *eax |
| Imm(%Ea) | M[Imm+R[Ea]] | 基址+位移 | 4(%eax) = *(4+eax) |
| (%Ea,%Eb) | M[R[Ea]+R[Eb]] | 變址 | (%eax,%ebx) = *(eax+ebx) |
| Imm(%Ea,%Eb) | M[Imm+R[Ea]+R[Eb]] | 基址+變址 | 9(%eax,%ebx) = *(9+eax+ebx) |
| (,%Ea,s) | M[R[Ea]*s] | 縮放變址 | (,%eax,4) = *(eax*4) |
| Imm(,%Ea,s) | M[Imm+R[Ea]*s] | 縮放變址+位移 | 0xfc(,%eax,4) = *(0xfc+eax*4) |
| (%Ea,%Eb,s) | M[R[Ea]+R[Eb]*s] | 縮放雙變址 | (%eax,%ebx,4) = *(eax+ebx*4) |
| Imm(%Ea,%Eb,s) | M[Imm+R[Ea]+R[Eb]*s] | 完整縮放定址 | 8(%eax,%ebx,4) = *(8+eax+ebx*4) |
資料傳送指令
| 指令 | 效果 | 說明 |
| movl S,D | D <-- S | 傳送雙字 (4 bytes) |
| movw S,D | D <-- S | 傳送字 (2 bytes) |
| movb S,D | D <-- S | 傳送位元組 (1 byte) |
| movsbl S,D | D <-- 符號擴展 S | 位元組擴展為雙字 (符號填充) |
| movzbl S,D | D <-- 零擴展 S | 位元組擴展為雙字 (零填充) |
| pushl S | 堆疊推入 | R[%esp]-=4; M[R[%esp]]=S |
| popl D | 堆疊彈出 | D=M[R[%esp]]; R[%esp]+=4 |
算術邏輯指令
| 指令 | 效果 | 說明 |
| leal S,D | D = &S | 載入有效位址 (僅限暫存器目的) |
| incl D | D++ | 加 1 |
| decl D | D-- | 減 1 |
| negl D | D = -D | 取負 |
| notl D | D = ~D | 按位取反 |
| addl S,D | D = D + S | 加法 |
| subl S,D | D = D - S | 減法 |
| imull S,D | D = D * S | 有號乘法 |
| xorl S,D | D = D ^ S | 異或 |
| orl S,D | D = D | S | 或 |
| andl S,D | D = D & S | 與 |
| sall k,D / shll k,D | D = D << k | 邏輯左移 |
| sarl k,D | D = D >> k | 算術右移 (保留符號) |
| shrl k,D | D = D >> k | 邏輯右移 (補零) |
特殊算術指令 (64 位元運算)
| 指令 | 效果 | 說明 |
| imull S | RDX:RAX = S * RAX | 有號 64 位元乘法 |
| mull S | RDX:RAX = S * RAX | 無號 64 位元乘法 |
| cltd | RDX:RAX = 符號擴展 RAX | 轉換為 64 位元 |
| idivl S | RDX = 餘數; RAX = 商 | 有號除法 |
| divl S | RDX = 餘數; RAX = 商 | 無號除法 |
條件碼暫存器
- CF (Carry Flag):無號溢位/借位
- OF (Overflow Flag):有號溢位
- ZF (Zero Flag):結果為零
- SF (Sign Flag):結果為負
比較與測試指令
| 指令 | 基於 | 說明 |
| cmpb/w/l S2,S1 | S1 - S2 | 比較 (設定條件碼) |
| testb/w/l S2,S1 | S1 & S2 | 測試 (設定條件碼) |
條件設定指令 (setcc)
| 指令 | 同義 | 條件 | 說明 |
| sete/setz D | | ZF | 相等/零 |
| setne/setnz D | | ~ZF | 不等/非零 |
| sets D | | SF | 負數 |
| setns D | | ~SF | 非負 |
| setg/setnle D | | ~(SF^OF) & ~ZF | 有號大於 |
| setge/setnl D | | ~(SF^OF) | 有號大於等於 |
| setl/setnge D | | SF^OF | 有號小於 |
| setle/setng D | | (SF^OF) | ZF | 有號小於等於 |
| seta/setnbe D | | ~CF & ~ZF | 無號大於 |
| setae/setnb D | | ~CF | 無號大於等於 |
| setb/setnae D | | CF | 無號小於 |
| setbe/setna D | | CF | ZF | 無號小於等於 |
條件跳轉指令 (jcc)
| 指令 | 同義 | 條件 | 說明 |
| jmp Label | | 1 | 無條件跳轉 |
| jmp *Operand | | 1 | 間接跳轉 |
| je/jz Label | | ZF | 相等/零 |
| jne/jnz Label | | ~ZF | 不等/非零 |
| js Label | | SF | 負數 |
| jns Label | | ~SF | 非負 |
| jg/jnle Label | | ~(SF^OF) & ~ZF | 有號大於 |
| jge/jnl Label | | ~(SF^OF) | 有號大於等於 |
| jl/jnge Label | | SF^OF | 有號小於 |
| jle/jng Label | | (SF^OF) | ZF | 有號小於等於 |
| ja/jnbe Label | | ~CF & ~ZF | 無號大於 |
| jae/jnb Label | | ~CF | 無號大於等於 |
| jb/jnae Label | | CF | 無號小於 |
| jbe/jna Label | | CF | ZF | 無號小於等於 |
控制轉移指令 (函式呼叫)
| 指令 | 說明 |
| call Label | 程序呼叫,返回位址入堆疊,跳轉至程序起始 |
| call *Operand | 間接呼叫 |
| leave | 恢復堆疊幀 (等同 mov %ebp,%esp; pop %ebp) |
| ret | 從程序返回 (彈出返回位址跳轉) |