gcc 擴充套件了 asm 支援

gcc 中的擴充套件 asm 支援具有以下語法:

asm [volatile] ( AssemblerTemplate
                  : OutputOperands
                  [ : InputOperands
                  [ : Clobbers ] ])
 
 asm [volatile] goto ( AssemblerTemplate
                       :
                       : InputOperands
                       : Clobbers
                       : GotoLabels)

其中 AssemblerTemplate 是彙編程式指令的模板,OutputOperands 是可以通過彙編程式碼修改的任何 C 變數,InputOperands 是用作輸入引數的任何 C 變數,Clobbers 是由彙編程式碼修改的列表或暫存器,GotoLabels 是可以在彙編程式碼中使用的任何 goto 語句標籤。

擴充套件格式在 C 函式中使用,是內聯彙編的更典型用法。下面是 Linux 核心中用於 ARM 處理器的位元組交換 16 位和 32 位數字的示例:

/* From arch/arm/include/asm/swab.h in Linux kernel version 4.6.4 */
#if __LINUX_ARM_ARCH__ >= 6

static inline __attribute_const__ __u32 __arch_swahb32(__u32 x)
{
    __asm__ ("rev16 %0, %1" : "=r" (x) : "r" (x));
    return x;
}
#define __arch_swahb32 __arch_swahb32
#define __arch_swab16(x) ((__u16)__arch_swahb32(x))

static inline __attribute_const__ __u32 __arch_swab32(__u32 x)
{
    __asm__ ("rev %0, %1" : "=r" (x) : "r" (x));
    return x;
}
#define __arch_swab32 __arch_swab32

#endif

每個 asm 部分使用變數 x 作為其輸入和輸出引數。然後 C 函式返回操作結果。

使用擴充套件的 asm 格式,gcc 可以按照用於優化 C 程式碼的相同規則優化 asm 塊中的彙編指令。如果你希望自己的 asm 部分保持不變,請使用 volatile 關鍵字作為 asm 部分。