内核代码中的asm和__asm__之间的区别

时间:2018-09-28 07:01:03

标签: assembly linux-kernel inline

我一直在寻找内核中如何使用内存屏障(Linux内核v4.19-rc5)。我不了解asm asm和__asm__之间的区别。例如,考虑障碍函数:

static inline void barrier(void)
{
    asm volatile("" : : : "memory");
}

此功能使用asmvolatile关键字,这是软件障碍。另一方面,考虑这样的硬件障碍:

#define mb()    __asm__ __volatile__("mb": : :"memory")

这次,使用了关键字__asm____volatile__。它们之间有什么区别?我从this的帖子中了解到,差异来自编译器,但我不明白为什么在相同的源代码中同时使用两个版本(__asm__asm)?

1 个答案:

答案 0 :(得分:3)

您是否已阅读@Ciro关于该问题的答案? What is the difference between 'asm', '__asm' and '__asm__'?

它说明asm__asm__相同,除了gcc -std=c99禁用asm,仅保留__asm__

asm__asm__的方便名称,在默认(-std=gnu99 / -std=gnu11或其他任何形式的GNU C模式下可用。


行为上的差异完全为零。 Linux的某些贡献者偏爱__asm__,而其他人则使用asm。 Linux是用-std=gnu99gnu11编译的,因为它肯定地依赖于C的GNU扩展。

我不认为这些情况中的任何一个都出现在可以包含在Linux之外的其他位置的标头中。 __asm__在GNU C代码中不是错误。但是,如果即使使用-std=c11进行编译也需要代码才能工作,那么asm是错误的。


只有MSVC的__asm关键字有所不同,并使用__asm { insn; insn; },主线gcc不支持。 (Apple的使用LLVM后端的OS X的旧版gcc支持-fasm-blocks,例如当前的Clang。)