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)。
情况是,您需要将寄存器传递给指令,但实际操作数在内存中。因此,您需要确保两个独立的事物,即:
- 你的指令在寄存器中获取操作数。这就是
r
约束所做的。 - 编译器知道你的
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 中多个输入和输出操作数的正确用法是啥?