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 部分。