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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GCC扩展了Asm - 了解clobbers和scratch register的用法相关的知识,希望对你有一定的参考价值。

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

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

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

这样做通常不会浪费寄存器,因为GCC可以将相同的寄存器用于这两个目的。但是,在这个asm中同时使用%1和%3作为x并且期望它们是相同的是愚蠢的。实际上,%3可能不是注册。它可能是x指向的对象的符号内存引用。

失去了我。

这个例子:

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

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

答案

什么是这个代码与另一个代码相比的附加价值?

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

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

  1. 你的指令在寄存器中获取操作数。这就是r约束所做的。
  2. 编译器知道你的asm块读取内存,因此必须在块之前刷新*x*y的值。这就是使用m约束的原因。

您不能使用%3而不是%1,因为m约束使用内存引用语法。例如。虽然%1可能像%r0%eax%3可能是(%r0)(%eax)甚至只是some_symbol。不幸的是,您的假设指令不接受这些操作数。

以上是关于GCC扩展了Asm - 了解clobbers和scratch register的用法的主要内容,如果未能解决你的问题,请参考以下文章

GCC 内联汇编错误:变量 '%al' 的 asm 说明符与 asm clobber 列表冲突

asm、asm volatile 和 clobbering memory 的区别

扩展 GCC asm 中多个输入和输出操作数的正确用法是啥?

如何在没有扩展内联 asm 的情况下在 gcc 内联汇编中声明和初始化局部变量?

x86 ASM - cpuid 是不是设置标志?

扩展内联汇编基础