为啥要在 ASM 中指定变量的地址而不是将其复制到寄存器中?

Posted

技术标签:

【中文标题】为啥要在 ASM 中指定变量的地址而不是将其复制到寄存器中?【英文标题】:Why specify address of variable in ASM instead of just copying it into register?为什么要在 ASM 中指定变量的地址而不是将其复制到寄存器中? 【发布时间】:2011-10-25 15:44:31 【问题描述】:

在我学习汇编的过程中(在 x86_64 上使用 GCC),我遇到了一些 SSE 示例,其中不只是将 C 变量复制到寄存器中,而是将地址复制到 EAX 中。既然可以这样做,为什么要这样做:

typedef float v4sf __attribute__((vector_size(16)));

typedef union 
    v4sf v;
    float f[4];
 Vec4;

Vec4 vector.v = (v4sf) 64.1,128.2,256.3,512.4 ;
float blah = 2.2;

__asm__("movups %0, %%xmm0 \n\t"
    "movups %1, %%xmm1 \n\t"
    "shufps $0x00, %%xmm1, %%xmm1 \n\t"
    "mulps %%xmm1, %%xmm0 \n\t"
    "movups %%xmm0, %0 \n\t"
    : "+m"(vector)
    : "m"(blah)
    : "%xmm0","%xmm1"
);

将向量复制到 xmm0(而不是将其保存在内存中)会导致性能下降吗?

这是我正在谈论的一个示例(它是 Intel 语法):

void powf_schlickSSE(const float * a, const float b, float * result)

    __asm 
        mov         eax, a              //load address of vector
        movss       xmm0, dword ptr [b] //load exponent into SSE register
        movups      xmm1, [eax]         //load vector into SSE register
        shufps      xmm0, xmm0, 0       //shuffle b into all floats
        movaps      xmm2, xmm1          //duplicate vector
        mov         eax, result         //load address of result
        mulps       xmm1, xmm0          //xmm1 = a*b
        subps       xmm0, xmm1          //xmm0 = b-a*b
        addps       xmm0, xmm2          //xmm2 = b-a*b+a
        rcpps       xmm0, xmm0          //xmm1 = 1 / (b-a*b+a)
        mulps       xmm2, xmm0          //xmm0 = a * (1 / (b-a*b+a))
        movups      [eax], xmm2         //store result
    

【问题讨论】:

您能否向我们展示具有您所描述行为的原始代码/程序集?很难确切地说出你在问什么。 当然,我在 Intel 语法中添加了一个示例。 该组件绝对不是最佳的。如今,除非您确定可以击败编译器,否则最好只使用内部函数。 您是在问使用 xmm 寄存器是否比在内存中保存向量慢? 是否有一个 pow() 函数可以对向量进行操作?如果没有,那我不用自己写吗? 【参考方案1】:

我可以看到多种原因

MSVC(英特尔语法代码的来源,对吗?)不支持将 __m128 值传递到汇编块中,或者至少编写代码的版本不支持。或者该版本可能根本不支持 SSE,除非通过内联汇编。

程序的其余部分没有处理向量类型,因此通过指针传递是最简单的解决方案。

【讨论】:

以上是关于为啥要在 ASM 中指定变量的地址而不是将其复制到寄存器中?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我必须在 Java 正则表达式中指定整个字符串? [复制]

为啥我需要在 Swift 的类中指定变量的类型?

如何在 R 中指定任意虚拟变量对比度? [复制]

为啥要在堆上而不是栈上分配内存? [复制]

如何让红移为复制命令中指定的字段添加当前时间

我可以将 asm 函数与 c - 字符串变量而不是字符串文字作为参数一起使用吗? [复制]