这段代码试图做什么?

时间:2014-12-18 13:07:57

标签: c gcc assembly macros inline-assembly

我试图了解以下代码的工作原理:

#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) ...
  • 之后

2 个答案:

答案 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表示这是一个内存操作数。