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

AT&T 與 Intel 匯編語法差異與 GCC 內嵌匯編完整指南

     編輯:關於C語言

一、AT&T vs Intel 語法核心差異

項目IntelAT&T
大小寫指令大寫指令小寫
運算元順序目的, 來源 (右←左)來源, 目的 (左→右)
暫存器前綴無% (如 %eax)
立即數前綴無$ (如 $1)
間接尋址[base+index*scale+disp]disp(base,index,scale)
運算大小後綴BYTE PTR 等b/w/l/q (如 movl)

範例對照


Intel:  MOV EAX, EBX
AT&T:   movl %ebx, %eax

Intel:  MOV EAX, [EBX+ECX*4+10h]
AT&T:   movl 0x10(%ebx,%ecx,4), %eax

二、GCC 內嵌匯編語法

基本格式


__asm__ __volatile__ (
  "assembly template"
  : output_operands   /* 輸出 */
  : input_operands    /* 輸入 */
  : clobbered_regs    /* 破壞描述 */
);

關鍵元件說明

  1. 範本:匯編指令字串,%0, %1... 為佔位符對應輸出/輸入
  2. 輸出部:"=r" (var) — = 唯寫,r 暫存器約束,var C 變數
  3. 輸入部:"r" (expr) — r 暫存器約束,expr C 運算式
  4. 約束字母:r 通用暫存器, m 記憶體, i 立即數, g 任意
  5. 破壞描述:列出被隱性修改的暫存器/記憶體 (如 "cc" 條件碼, "memory")

完整範例:原子加法


int atomic_add(int *ptr, int val) {
  int old;
  __asm__ __volatile__ (
    "lock; xaddl %1, %0"
    : "+m" (*ptr), "=r" (old)
    : "1" (val)
    : "memory", "cc"
  );
  return old;
}
  • +m 讀寫記憶體操作數
  • "1" (val) 指定 %1 使用與輸出 %1 同一暫存器
  • lock 前綴確保總線鎖定 (多核心原子性)

三、GCC 編譯內嵌匯編流程

  1. 解析約束,分配暫存器/記憶體位置
  2. 產生暫存器保存/恢復代碼 (如需要)
  3. 展開範本,替換佔位符為實際暫存器/位址
  4. 插入輸出寫回、輸入載入指令
  5. 輸出最終匯編檔

四、實務建議

  • 優先使用編譯器內建函數 (__sync_*, __atomic_*) 替代手寫原子操作
  • 複雜邏輯寫獨立 .s 檔,以 .globl 導出,C 端 extern 呼叫
  • 善用 __asm__ goto (GCC 4.5+) 實現控制流跳轉
  • 永遠標註 __volatile__ 防止編譯器優化移除/重排
  • 破壞描述務必完整,避免編譯器假設暫存器未變而產生錯誤代碼
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved