当嵌入汇编代码为C / C ++程序,就可以避免通过用推指令保存它们破坏寄存器(或编译器支持它指定撞列表)。

如果您是包括装配直列,并希望避免压入和弹出破坏的寄存器的开销,有没有让GCC供您选择寄存器(例如那些它知道其中没有任何有用的信息)的一种方式。

有帮助吗?

解决方案

是。您可以指定你想要一个特定变量(输入或输出)存储在寄存器中,但你没有指定一个寄存器。请参见进行了详细解释这个文件。基本上,内联组件看起来像这样:

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 */
   );

其他提示

编译器内在是一个非常有用的方式混合组件和C / C ++代码。他们的声明看起来像函数,但实际上直接编译到单个本地指令(通过编译器内的特殊情况)。这给了你多少组装工作的控制,但保留登记着色和调度到编译器。

一个优点是,则可以通过一个普通的C变量成本征的,并且让编译器采取加载它到寄存器和它周围的调度其他OPS照顾。例如,

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
}

OK,所以我不能发表评论上面,但我敢肯定,正确的语法(与上面所述的不同)是:

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

尽管可以离开的输入和输出寄存器的分配给编译器,有留下划痕/临时寄存器中的分配的没有明显的方式(即使用的中间值而不是一个输入或输出)给编译器。从历史上看,我刚刚上市的明确他们在撞列表(例如,“%XMM1”,“%RCX”),但我现在认为这可能会更好列出它们为输出为了让编译器来选择它们。我不知道确切解决此问题的任何来源。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top