G ++ Asm inline:注册clobbering

时间:2013-07-07 15:02:18

标签: assembly g++ sse inline-assembly avx

如果我在clobber列表中没有写任何内容,gcc编译器是否使用push / pop进行寄存器备份?输入和输出列表寄存器会发生什么?

我将制作一个简短的asm内联,将一些通用寄存器保存到XMM / YMM寄存器,然后在通用寄存器上播放。最后,原始值从XMM / YMM寄存器返回到通用寄存器。编译器是否会使用push / pops来保存它们?

我怎么能告诉GCC编译器:"不要为我推送/弹出enything,我正在使用XMM / YMM来实现这个目的。也许我会自己推/弹#34;

类似的东西:

__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
    );

或类似的东西(我知道这种交换速度非常慢,只是想推送pop工作):

__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
    );

1 个答案:

答案 0 :(得分:1)

这个问题有点棘手。据我所知,编译方式会对结果产生影响。我不确定这是否是您需要的,但如果您不使用内联汇编,则可以控制它。

您在单独的.s文件中编写代码,并使用-O3等优化进行编译,gcc不会推送和保护非易失性寄存器。我自己不使用内联汇编,所以我不清楚那部分。你可以自己测试一下:D

BTW:我想如果你编写.asm文件并使用nasm编译它并用gcc链接对象,同样的事情就会发生。通过优化,我不认为gcc会自动执行push / pop。如果我的回复有问题,请告诉我。感谢。

祝你好运

xiangpisaiMM