3

将汇编代码嵌入到 C/C++ 程序中时,您可以通过使用 push 指令保存寄存器来避免破坏寄存器(或指定编译器支持它的 clobber 列表)。

如果您包含汇编内联并希望避免推送和弹出破坏寄存器的开销,有没有办法让 gcc 为您选择寄存器(例如,它知道其中没有有用信息的寄存器)。

4

3 回答 3

9

是的。您可以指定要将特定变量(输入或输出)存储在寄存器中,但不必指定寄存器。有关详细说明,请参阅此文档。本质上,内联程序集如下所示:

asm("your assembly instructions"
      : output1("=a"),  // I want output1 in the eax register
        output2("=r"),  // output2 can be in any general-purpose register
        output3("=q"),  // output3 can be in eax, ebx, ecx, or edx
        output4("=A")   // output4 can be in eax or edx
      : /* inputs */
      : /* clobbered registers */
   );
于 2009-05-31T00:22:44.337 回答
0

编译器内在函数是混合汇编和 C/C++ 代码的一种非常有用的方法。它们是看起来像函数的声明,但实际上直接编译为单独的本机指令(通过编译器内的特殊情况)。这为您提供了在汇编中工作的大部分控制权,但将寄存器着色和调度留给了编译器。

一个优点是您可以将一个普通的 C 变量传递给一个内部变量,并让编译器负责将其加载到寄存器上并围绕它调度其他操作。例如,

struct TwoVectors
{
   __m128 a; __m128b;
}

// adds two vectors A += B using the native SSE opcode
inline void SimdADD( TwoVectors *v ) 
{
   v->a = _mm_add_ps( v->a , v->b ); // compiles directly to ADDSS opcode
}
于 2010-11-18T10:01:09.363 回答
0

好的,所以我不能在上面发表评论,但我很确定正确的语法(与上面显示的不同)是:

asm ( "your assembly instructions"
    : "=a"(output1),
      "=r"(output2),
      "=q"(output3),
      "=A"(output4)
    : /* inputs */
    : /* clobbered registers */
);

尽管您可以将输入和输出寄存器的分配留给编译器,但没有明显的方法可以将暂存/临时寄存器(即用于中间值但不用于输入或输出)的分配留给编译器。从历史上看,我只是在 clobber 列表中明确列出它们(例如“%xmm1”、“%rcx”),但我现在认为最好将它们列为输出以便让编译器选择它们。我不知道有任何来源可以明确解决这个问题。

于 2012-08-07T22:15:08.473 回答