0

clobber リストに何も記述しない場合、gcc コンパイラはレジスタのバックアップに push/pop を使用しますか? 入力リストレジスタと出力リストレジスタはどうなりますか?

いくつかの汎用レジスターを XMM/YMM レジスターに保存し、汎用レジスターで再生する短い asm インラインを作成します。最後に、元の値が XMM/YMM レジスタから汎用レジスタに戻されます。とにかく、コンパイラはそれらを保存するためにプッシュ/ポップを配置しますか?

GCCコンパイラにどのように伝えることができますか:

何かのようなもの:

__asm__ __volatile__ (
        ".intel_syntax noprefix \n\t"
        "movd xmm0,eax \n\t"//storing in xmm registers instead of   pushing
        "movd xmm1,ebx \n\t"
        "movd xmm2,ecx \n\t"
        "movd xmm3,edx \n\t"
        "movd xmm4,edi \n\t" // end of  backups
        //.
        //... doing work
        //.
        "movd edi,xmm4 \n\t"
        "movd edx,xmm3 \n\t"
        "movd ecx,xmm2 \n\t"
        "movd ebx,xmm1 \n\t"
        "movd eax,xmm0 \n\t" // end of pops

        ://outputs
        "=g"(x[0]),  //%0
        "=g"(x[1])   //%1
        ://inputs
        "g"(x[0]),  //%2
        "g"(x[1])   //%3
        ://no clobber list
    );

またはこのようなもの(このスワッピングが非常に遅いことは知っていますが、プッシュポップを機能させたかっただけです):

__asm__ __volatile__ (
        ".intel_syntax noprefix \n\t"
        "push rax \n\t"
        "push rbx \n\t"
        "push rcx \n\t"
        "push rdx \n\t"

        "mov eax,%2 \n\t"
        "mov ecx,%3 \n\t"
        "mov edx,eax \n\t"
        "mov eax,ecx \n\t"
        "mov ecx,edx \n\t"
        "mov %0,eax \n\t"
        "mov %1,ecx \n\t"

        "pop rdx \n\t"
        "pop rcx \n\t"
        "pop rbx \n\t"
        "pop rax \n\t"

        ://outputs
        "=g"(x[0]),  //%0
        "=g"(x[1])   //%1
        ://inputs
        "g"(x[0]),  //%2
        "g"(x[1])   //%3
        ://no clobber list
    );
4

1 に答える 1

1

この質問はちょっと難しいです。私の知る限り、コンパイルの方法は結果に影響を与えます。これが必要かどうかはわかりませんが、インライン アセンブリを使用しない場合は制御できます。

コードを別の .s ファイルに記述し、-O3 などの最適化を使用してコンパイルすると、gcc は不揮発性レジスタをプッシュおよび保護しません。私は自分でインラインアセンブリを使用していないので、その部分については明確ではありません。自分でテストできます:D

ところで: .asm ファイルを作成し、nasm を使用してコンパイルし、オブジェクトを gcc にリンクすると、同じことが起こると思います。最適化により、gcc が自動的にプッシュ/ポップを行うとは思えません。私の返信に何か問題がある場合はお知らせください。ありがとう。

幸運を

xiangpisaiMM

于 2013-07-07T15:46:20.133 に答える