GCC扩展了Asm - 了解clobbers和scratch register的用法

时间:2018-03-02 10:31:07

标签: gcc assembly inline-assembly

关于 Extended ASM - Clobbers and Scratch Registers 的GCC文档,我发现很难理解以下解释和示例:

  

这是一个虚构的平方和指令,需要两个   指向内存中浮点值的指针并产生浮动   点寄存器输出。请注意,x和y都在两次出现   asm参数,一次指定访问的内存,一次指定一个   asm使用的基址寄存器。

好的,第一部分理解,现在句子继续:

  

你通常不会浪费一个   通过这样做来注册,因为GCC可以为两者使用相同的寄存器   目的。但是,将%1和%3用于x in将是愚蠢的   这个asm并期望它们是一样的。事实上,%3可能不是一个   寄存器。它可能是对象的符号内存引用   由x指出。

失去了我。

示例:

asm ("sumsq %0, %1, %2"
     : "+f" (result)
     : "r" (x), "r" (y), "m" (*x), "m" (*y));

这个例子和句子的第二部分告诉我们什么?什么是这个代码与另一个代码相比的附加价值?这段代码是否会导致更高效的内存刷新(如本章前面所述)?

1 个答案:

答案 0 :(得分:3)

  

与其他代码相比,此代码的附加价值是多少?

哪个“另一个”?我看待它的方式,如果你有这种指令,你几乎必须使用这个代码(唯一的选择是通用的memory clobber)。

情况是,您需要将寄存器传递给指令,但实际操作数在内存中。因此,您需要确保两个不同的东西,即:

  1. 你的指令在寄存器中获取操作数。这就是r约束的作用。
  2. 编译器知道您的asm块读取内存,因此必须在块之前刷新*x*y的值。这就是m约束的用途。
  3. 您无法使用%3代替%1,因为m约束使用内存引用语法。例如。虽然%1可能类似于%r0%eax,但%3可能是(%r0)(%eax)甚至只是some_symbol。不幸的是,你的假设指令不接受这些操作数。