首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 組合語言

AT&T x86 組合語言語法完全指南:與 Intel 語法差異對照

     編輯:組合語言

DJGPP、GCC 內聯組合語言、Linux 核心開發均採用 AT&T 語法。它與主流的 Intel 語法(MASM/TASM/NASM)有顯著差異。本文系統整理核心差異,附對照表與實例,幫助開發者快速轉換。

核心語法差異總覽

項目Intel 語法AT&T 語法
運算元順序目的, 來源來源, 目的 (顛倒)
暫存器前綴無% (如 %eax)
立即數前綴無$ (如 $1)
記憶體運算元大小BYTE PTR, WORD PTR, DWORD PTR指令尾碼 b(8-bit), w(16-bit), l(32-bit)
記憶體定址[base + index*scale + disp]disp(base, index, scale)
段暫存器seg:[offset]seg:offset 或 %seg:offset

指令對照實例

Intel                  AT&T
mov ax, bx             movw %bx, %ax
xor eax, eax           xorl %eax, %eax
mov ax, 1              movw $1, %ax
mov ah, byte ptr X     movb X, %ah
mov ax, word ptr X     movw X, %ax
mov eax, X             movl X, %eax

註:movw = 16-bit, movl = 32-bit, movb = 8-bit。

特殊指令映射

Intel          AT&T
movsx          movsSD  (S=來源大小, D=目的大小, 如 movswl %ax, %ecx)
movzx          movzSD
cbw            cbtw
cwde           cwtl
cwd            cwtd
cdq            cltd
call far S:O   lcall $S, $O
jmp far S:O    ljmp $S, $O
ret far V      lret $V

記憶體定址對照

Intel                    AT&T
mov eax, [ebp+4]         movl 4(%ebp), %eax
add ecx, [eax+eax*4]     addl (%eax,%eax,4), %ecx
mov fs:eax, 4            movb $4, %fs:(%eax)
mov eax, [4*eax+array]   movl _array(,%eax,4), %eax
mov cx, [ebx+4*eax+array]movw _array(%ebx,%eax,4), %cx

跳轉指令限制

jcxz, jecxz, loop, loopz, loope, loopnz, loopne 僅支援短跳轉(-128~+127)。長跳轉需展開:

jcxz foo   →   jcxz cx_zero
               jmp cx_nonzero
             cx_zero:
               jmp foo
             cx_nonzero:

MUL/IMUL 指令差異

AT&T 單運算元 imul %ebx 為擴展乘法(結果在 EDX:EAX)。雙運算元 imul %ebx, %eax 為非擴展乘法(結果在 EAX),對應 Intel imul eax, ebx。

GCC 內聯組合語言語法

__asm__( "asm statements" : outputs : inputs : clobbers );
  • asm statements:AT&T 指令,換行用 \n 或 ;
  • outputs:輸出運算元,格式 "=constraint" (c_var),= 表示唯寫
  • inputs:輸入運算元,格式 "constraint" (c_var)
  • clobbers:被修改的暫存器/記憶體,如 "eax", "memory"

範例 1:僅輸入,無輸出

int i = 0;
__asm__(
  "pushl %%eax\n"
  "movl %0, %%eax\n"
  "addl $1, %%eax\n"
  "movl %%eax, %0\n"
  "popl %%eax"
  :              /* 無輸出 */
  : "g" (i)      /* 輸入:i,g=任意位置 */
  : "eax"        /* 修改 eax(雖然 push/pop 保護,但建議宣告)*/
);  // i++

範例 2:輸入 + 輸出

int i=0, j=1, k=0;
__asm__ __volatile__(
  "pushl %%eax\n"
  "movl %1, %%eax\n"
  "addl %2, %%eax\n"
  "movl %%eax, %0\n"
  "popl %%eax"
  : "=g" (k)       /* %0 = k (輸出) */
  : "g" (i), "g" (j)  /* %1 = i, %2 = j (輸入) */
  : "eax", "memory"
);  // k = i + j

編號規則:輸出優先編號 %0..%K-1,輸入接著 %K..%N-1。

標號與跳轉

內聯組合語言標號需加 b(向後)或 f(向前)後綴:

__asm__(
  "0:\n"
  "...\n"
  "jmp 0b\n"   /* 跳回標號 0 */
  "...\n"
  "jmp 1f\n"   /* 跳往標號 1 */
  "...\n"
  "1:\n"
);

獨立組合語言檔案架構

.file "myasm.S"
.data
somedata: .word 0
.text
.globl __myasmfunc
__myasmfunc:
  ...
  ret

使用 gcc -S file.c 產生 .S 參考編譯器輸出慣例。

巨集簡化開發

包含 libc/asmdefs.h 使用巨集:

#include 
.file "myasm.S"
.data
.align 2
somedata: .word 0
.text
.align 4
FUNC(__MyExternalAsmFunc)
ENTER
movl ARG1, %eax
...
jmp mylabel
...
mylabel:
...
LEAVE

FUNC/ENTER/LEAVE/ARG1 等巨集處理函數序言/結語、參數存取,提高可移植性。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved