2009-05-31 38 views
3

将程序集代码嵌入到C/C++程序中时,可以通过使用推送指令(或指定编译器支持的clobber列表支持它)来避免使用clobbering寄存器。将程序集嵌入到C中,编译器为您找到寄存器

如果你包含内联程序集,并且希望避免推送和弹出clobbered寄存器的开销,有没有办法让gcc为你选择寄存器(例如,它知道没有有用的信息)。

+0

请添加'家庭作业'标签,同时请注意,这并不意味着它只是一个家庭作业的网站,因此您必须提供您目前为止所提供的内容,供其他人参加并提供其余的部分。 – none 2009-05-31 00:22:50

+0

不确定你的意思。这是一个理论问题,所以目前还没有“代码”。 – bugmenot77 2009-05-31 00:30:48

+3

为什么你认为这是作业?我从来没有做过功课,询问我有关使用gcc的详细信息。这是一旦你真正尝试在现实世界中实现某些东西时所面临的问题。 – nosatalian 2009-05-31 01:18:41

回答

9

是的。您可以指定您希望将特定变量(输入或输出)存储在寄存器中,但不必指定寄存器。有关详细说明,请参阅this document。从本质上讲,内联汇编如下:

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

谢谢!我实际上在发布之前浏览了该文件,但错过了它。现在花了很长时间来阅读这些小部分,我可以看到为什么!这并不漂亮,但它的工作原理。再次感谢。 – bugmenot77 2009-05-31 00:42:24

0

Compiler intrinsics是混合汇编和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 
} 
0

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

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

虽然你可以将输入和输出寄存器分配给编译器,但没有明显的方式将划分/临时寄存器(即,用于中间值而不是输入或输出)分配给编译器。历史上,我只是在clobber列表中明确列出了它们(例如“%xmm1”,“%rcx”),但我现在认为将它们列为输出以便编译器选择它们可能会更好。我不知道任何来源明确地解决这个问题。

相关问题