为什么GCC向我的内联程序集中添加程序集命令?

为什么GCC向我的内联程序集中添加程序集命令?,gcc,inline-assembly,llvm-gcc,Gcc,Inline Assembly,Llvm Gcc,我正在使用Apple的llvm gcc编译一些带有内联汇编的代码。我写了我想让它做的,但它添加了一些无关的命令,这些命令会将变量写入内存。它为什么要这样做?我怎样才能阻止它 例如: __asm__{ mov r11, [rax] and r11, 0xff cmp r11, '\0' } 变为(在“装配”助手视图中): 干杯。这是因为gcc试图优化您的代码。您可以通过将-O0添加到命令行来防止优化。如果您不想在asm\uuuuu之后添加volatile。其他命令可能是上一个/下一个

我正在使用Apple的llvm gcc编译一些带有内联汇编的代码。我写了我想让它做的,但它添加了一些无关的命令,这些命令会将变量写入内存。它为什么要这样做?我怎样才能阻止它

例如:

__asm__{
  mov r11, [rax]
  and r11, 0xff
  cmp r11, '\0'
}
变为(在“装配”助手视图中):


干杯。

这是因为gcc试图优化您的代码。您可以通过将
-O0
添加到命令行来防止优化。

如果您不想在asm\uuuuu之后添加volatile。其他命令可能是上一个/下一个C指令的一部分。如果没有volatile编译器,则允许它执行此操作(因为它可能以这种方式执行得更快—不是您的代码,而是整个例程)。

您需要使用GCC来告诉它您正在使用哪些寄存器作为输入和输出,以及哪些寄存器被破坏。如果不这样做,它就不知道你在做什么,它生成的程序集很容易干扰你的代码


通过告诉它您的代码正在做什么,它改变了它如何进行寄存器分配和优化,并避免破坏您的代码。

您是否尝试过使用@Adam设置适当的输入、输出和缓冲列表?这是我最好的猜测。。。我今天就试试。我是否必须切换到
asm(“cmd1\n\t”“cmd2”:…:)
样式,或者是否有方法将说明符添加到花括号表示法?我不知道是否有方法使用花括号表示法添加这些说明符;将其转换为使用带引号的字符串应该不会太难。@Adam看起来这样可以修复它——如果你想获得适当的信任,可以将其作为答案发布:)在询问之前,我在谷歌上搜索了一下,这是第一件事。唉,编译器忽略了这一点(并发出警告说这样做)。我不认为额外的命令来自函数中的其他地方,因为它会两次移动到同一个内存中,有效地使第一次移动成为nop。
mov  0(%rax), %r11     // correct
movq %r11, -104(%rbp)  // no, GCC, obviously wrong
and  $255, %r11
movq %r11, -104(%rbp)
cmp  $0, %r11