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