Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
volatile关键字不适用于gcc内联程序集_Gcc_Assembly_Optimization_Inline_Volatile - Fatal编程技术网

volatile关键字不适用于gcc内联程序集

volatile关键字不适用于gcc内联程序集,gcc,assembly,optimization,inline,volatile,Gcc,Assembly,Optimization,Inline,Volatile,我需要运行以下简单的内联汇编代码: #include <stdio.h> int count; int main() { count = 0; for (int i = 0; i < 10; i++) { asm volatile ("incl count"); // count++ } printf("count=%d\n", count); return 0; } 在我打开优化gcc-O1之前,它可以精细打印count=10,在这

我需要运行以下简单的内联汇编代码:

#include <stdio.h>

int count;

int main() {

  count = 0;
  for (int i = 0; i < 10; i++) {
    asm volatile ("incl count");  // count++
  }

  printf("count=%d\n", count); 

  return 0;
}

在我打开优化gcc-O1之前,它可以精细打印count=10,在这种情况下,它打印count=0。我读到volatile限定符将阻止优化器将代码置于循环之外。但在这里似乎没有效果

发现问题。我必须将全局变量计数定义为volatile。问题在于没有将asm块排除在循环之外。编译器只是在printf中将count替换为0

volatile int count;

int main() {

  count = 0;
  for (int i = 0; i < 10; i++) {
    asm volatile ("incl count");  // count++
  }

  printf("count=%d\n", count); 

  return 0;
}

GCC手册强烈建议您不要在内联程序集中按名称访问全局变量。您应该通过输入和输出约束传递变量。类似于asm的内容,包括%0:+rmcount;无论count是局部变量还是全局变量,都应该有效。在不使用输入/输出操作数(如直接从汇编程序模板使用全局符号)的情况下从C程序访问数据的状态可能无法按预期工作。如果查看生成的代码(如使用-S),您将看到gcc没有将asm从循环中拉出。它仍在调用它10次。但是,由于gcc对asm语句中发生的事情的可见性为零,因此它没有理由假设计数受到影响,因此优化器可以自由地假设它从不改变初始值0。从中可以看出:GCC不解析汇编指令本身,也不知道它们的意思,甚至不知道它们是否是有效的汇编输入。这不是真正的问题,也不是一个正确的解决方案,真正的问题是,您不正确地使用了内联汇编,请参阅Michael的评论。这可能不是一个好的解决方案。但在这种情况下,这才是真正的问题所在。我查看了编译器优化后生成的汇编代码。要调用printf,它有一条指令pushl 0来推送参数,而不是将count定义为volatile后的pushl count it printed count=10是的,您现在有了工作代码,但您的修复程序不是修复程序,如果您尝试创建更复杂的程序并以同样的方式修复它,它最终会崩溃。此外,挥发物会完全杀死C部分。这让我完全困惑,为什么你要把这些工具推到不应该使用的地方,并且在文档中建议不要这样推它们,如果你想学习汇编,为什么不编写更纯粹的汇编函数呢?这比学习汇编容易得多,更重要的是,还要学习gcc内联汇编规则,或者,在更糟糕的情况下,您实际上是在尝试创建一些C代码的性能优化。。。现在,您的方法对于学习汇编有些有效,我只是觉得它太多太乱了,建议您先使用asm,然后再学习内联规则。但如果您追求的是性能,那么您当前的解决方案是完全错误的,方向正好相反。而是使用C++count;,它会结束得更好更快、更短等等。。。