这只是使用"memory"时,GCC会保证做到的一点,但这并不是全部。因为使用"memory"是向GCC声明内存发生了变化,而内存发生变化带来的影响并不止这一点。比如我们在前面讲到的例子:
int main(int __argc, char* __argv[])
{
int* __p = (int*)__argc;
(*__p) = 9999;
__asm__("":::"memory");
if((*__p) == 9999)
return 5;
return (*__p);
}
本 例中,如果没有那条内联汇编语句,那个if语句的判断条件就完全是一句废话。GCC在优化时会意识到这一点,而直接只生成return 5的汇编代码,而不会再生成if语句的相关代码,而不会生成return (*__p)的相关代码。但你加上了这条内联汇编语句,它除了声明内存变化之外,什么都没有做。但GCC此时就不能简单的认为它不需要判断都知道 (*__p)一定与9999相等,它只有老老实实生成这条if语句的汇编代码,一起相关的两个return语句相关代码。
当一个内联汇编 指令中包含影响eflags寄存器中的条件标志(也就是那些Jxx等跳转指令要参考的标志位,比如,进位标志,0标志等),那么需要在 Clobber/Modify域中使用"cc"来声明这一点。这些指令包括adc, div,popfl,btr,bts等等,另外,当包含call指令时,由于你不知道你所call的函数是否会修改条件标志,为了稳妥起见,最好也使用 "cc"。
我很少在相关资料中看到有关"cc"的确切用法,只有一份文档提到了它,但还不是i386平台的,只是说"cc"是处理器平台 相关的,并非所有的平台都支持它,但即使在不支持它的平台上,使用它也不会造成编译错误。我做了一些实验,但发现使用"cc"和不使用"cc"所生成的代 码没有任何不同。但Linux 2.4的相关代码中用到了它。如果谁知道在i386平台上"cc"的细节,请和我联系。
另外,还可以在 Clobber/Modify域指定数字0到9,以声明第n个Input/Output操作表达式所使用的寄存器发生了变化,但正如我们在前面所提到的, 如果你为某个Input/Output操作表达式指定了寄存器,或使用"g","r"等约束让GCC为其选择寄存器,GCC已经知道哪个寄存器内容发生了 变化,所以这么做没有什么意义;我也作了相关的试验,没有发现使用它会对GCC生成的汇编代码有任何影响,至少在i386平台上是这样。Linux 2.4的所有i386平台相关内联汇编代码中都没有使用这一点,但S390平台相关代码中有用到,但由于我对S390汇编没有任何概念,所以,也不知道这 么做的意义何在。
总结
以上所述是小编给大家介绍的C语言ASM汇编内嵌语法详解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对易采站长站网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!










