0

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

我将做一个简短的 asm 内联,将一些通用寄存器保存到 XMM/YMM 寄存器,然后在通用寄存器上播放。最后,原始值从 XMM/YMM 寄存器返回到通用寄存器。编译器会放推/弹出来保存它们吗?

我如何告诉 GCC 编译器:“不要为我推送/弹出任何内容,我正在为此目的使用 XMM/YMM。也许我会自己推送/弹出”

就像是:

__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 不会自动进行推送/弹出。让我知道我的回复是否有问题。谢谢。

祝你好运

相皮赛MM

于 2013-07-07T15:46:20.133 回答