我试图了解以下代码的工作原理:
#define M32toX128(x128,m32) __asm__ \
("movddup %1, %0\n\t" \
"movsldup %0, %0" \
: "=&x"(x128) : "m"(m32) )
我只有基本的装配知识。在使用它的程序的上下文中搜索,我已经理解它复制了32位变量并将结果存储在128位变量中。
我的问题是:
%0
和%1
指的是什么? :
)在做什么?%n
s,"=&x"(x128)
... 答案 0 :(得分:2)
gcc内联汇编是一个复杂的野兽,太复杂,无法在此详细描述。
作为快速概述,asm块的一般形式是:"template" : outputs : inputs : clobbers
。您可以使用%
后跟基于零的索引来引用模板中的输出和输入(统称为操作数)。因此%0
引用x128
而%1
引用m32
。对于每个操作数,您可以指定一个约束,告诉编译器如何分配所述操作数。 =&x
表示在任何可用的xmm寄存器中将x128
分配为早期删除输出,m
表示使用操作数的内存地址。有关令人难以置信的详细信息,请参阅manual。
生成的实际程序集将取决于编译器使用的操作数选择。如果使用-S
选项要求汇编列表,则可以看到。假设m32
是局部变量,代码可能如下所示:
movddup x(%esp), %xmmN
movsldup %xmmN, %xmmN
请注意,gcc内联汇编程序当然是gcc和特定于体系结构的,这意味着使用等效的编译器内在函数更简单。
答案 1 :(得分:2)
此代码将从GCC传递到汇编程序阶段。宏的某些部分将在此过程中被替换。以下是文档:http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html
%0
和%1
将替换为您传递给C宏的值。
:
用于分隔宏的各个部分。第一个必修部分是模板。第二个用于输出操作数。完整见http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html#s5。
在这种情况下,您有一个输出=
,它是128位(x
),并由宏进行了删除(&
)。 m
表示这是一个内存操作数。