【问题标题】:Why does GCC add assembly commands to my inline assembly?为什么 GCC 将汇编命令添加到我的内联汇编中?
【发布时间】:2012-05-17 12:09:51
【问题描述】:

我正在使用 Apple 的 llvm-gcc 来编译一些带有内联汇编的代码。我写了我想要它做的事情,但是它添加了一些无关的命令,这些命令不断地将变量写入内存。为什么会这样?我该如何阻止它?

例子:

__asm__{
  mov r11, [rax]
  and r11, 0xff
  cmp r11, '\0'
}

成为(在“装配”助手视图中):

mov  0(%rax), %r11     // correct
movq %r11, -104(%rbp)  // no, GCC, obviously wrong
and  $255, %r11
movq %r11, -104(%rbp)
cmp  $0, %r11

干杯。

【问题讨论】:

  • 您是否尝试过使用extended asm syntax 设置适当的输入、输出和破坏列表?
  • @Adam,这是我最好的猜测......我今天会试试。我是否必须切换到asm("cmd1\n\t" "cmd2" : ... : ... : ... ) 样式,或者有没有办法将说明符添加到大括号符号中?
  • 我不知道是否有办法使用花括号表示法添加这些说明符;将其转换为使用带引号的字符串应该不会太难。
  • @Adam 看起来像这样修复了它——如果你想要适当的信用,请将它作为答案发布:)

标签: gcc inline-assembly llvm-gcc


【解决方案1】:

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

通过告知它您的代码在做什么,它会改变它进行寄存器分配和优化的方式,并避免破坏您的代码。

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      如果您不想要,请尝试在 __asm__ 之后添加 volatile。附加命令可能是上一个/下一个 C 指令的一部分。如果没有 volatile 编译器,则允许这样做(因为它可能以这种方式执行得更快——不是你的代码,而是整个例程)。

      【讨论】:

      • 我在问之前做了一些谷歌搜索,这是第一件事。唉,编译器忽略了它(并发出了这样的警告)。我不认为附加命令来自函数的其他地方,因为它两次移动到相同的内存,有效地使第一次移动成为 nop。
      猜你喜欢
      • 2012-10-20
      • 1970-01-01
      • 1970-01-01
      • 2019-05-11
      • 1970-01-01
      • 1970-01-01
      • 2016-10-07
      • 1970-01-01
      • 2012-02-12
      相关资源
      最近更新 更多