コンパイラはあなたのためのレジスタを見つけるとCにアセンブリを埋め込みます
-
06-09-2019 - |
質問
C / C ++プログラムにアセンブリコードを埋め込む場合、あなたはプッシュ命令でそれらを保存することで、レジスタをつかう避けることができます(またはコンパイラがそれをサポートするのクロバーリストを指定します)。
あなたは、アセンブリのインライン含むとレジスタを上書きさ押すとポップのオーバーヘッドを回避したい場合は、、gccはあなた(それはそれで有用な情報を持っていない知っているなどのもの)のためのレジスタを選択させるの方法があります。
解決
はい。あなたが特定の変数(入力または出力)をレジスタに格納したいことを指定することができますが、レジスタを指定する必要はありません。詳細な説明については、このドキュメントにrel="noreferrer">
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変数を渡すと、コンパイラはレジスタにそれをロードし、その周りに他の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」)が、私は今ではそれらを選択するようにコンパイラを可能にするために出力としてそれらをリストアップする方が良いかもしれないと思います。私は決定的にこの問題に対処する任意のソースを知りません。