c - 在 C 中使用内联汇编的错误

标签 c assembly gcc inline-assembly mmx

我正在尝试汇编以使用 vector 运算,这是我以前从未真正使用过的,而且我承认在掌握一些语法方面遇到了一些麻烦。

相关代码如下。

unit16_t asdf[4];
asdf[0] = 1;
asdf[1] = 2;
asdf[2] = 3;
asdf[3] = 4;
uint16_t other = 3;

__asm__("movq %0, %%mm0"
        :
        : "m" (asdf));
__asm__("pcmpeqw %0, %%mm0"
        :
        : "r" (other));
__asm__("movq %%mm0, %0" : "=m" (asdf));

printf("%u %u %u %u\n", asdf[0], asdf[1], asdf[2], asdf[3]);

在这个简单的示例中,我试图对数组中的每个元素进行“3”的 16 位比较。我希望输出是“0 0 65535 0”。但它甚至不会组装。

第一个汇编指令给我以下错误:

错误:内存输入 0 不可直接寻址

第二条指令给了我一个不同的错误:

错误:“pcmpeqw”的后缀或操作数无效

如有任何帮助,我们将不胜感激。

最佳答案

您不能在 gcc asm 语句中直接使用寄存器并期望它们与其他 asm 语句中的任何内容相匹配——优化器会四处移动。相反,您需要声明适当类型的变量并使用约束将这些变量强制放入您正在使用的指令的正确类型的寄存器中。

MMX/SSE 的相关约束是 xmm 寄存器的 x 和 mmx 寄存器的 y。对于您的示例,您可以执行以下操作:

#include <stdint.h>
#include <stdio.h>

typedef union xmmreg {
    uint8_t   b[16];
    uint16_t  w[8];
    uint32_t  d[4];
    uint64_t  q[2];
} xmmreg;

int main() {
    xmmreg v1, v2;
    v1.w[0] = 1;
    v1.w[1] = 2;
    v1.w[2] = 3;
    v1.w[3] = 4;
    v2.w[0] = v2.w[1] = v2.w[2] = v2.w[3] = 3;
    asm("pcmpeqw %1,%0" : "+x"(v1) : "x"(v2));
    printf("%u %u %u %u\n", v1.w[0], v1.w[1], v1.w[2], v1.w[3]);
}

请注意,您需要在第二个 vector 的所有相关元素中显式复制 3

关于c - 在 C 中使用内联汇编的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21995904/

相关文章:

c - 如何使用 CMake 将我的库与 czmq 链接

delphi - 如何获取内部System.pas函数的地址?

c++ - 为什么对 c 和 c++ 使用 gcc 和 g++ 编译器驱动程序

我可以同时将内存分配给不同的结构指针吗?

c - sscanf 1 字节十六进制数据,无溢出

c++ - 在c++中通过字符串获取输入

c++ - Switch case 程序在某个点不断循环。想不通

linux - 程序启动时的默认寄存器状态是什么(asm,linux)?

python - python setup.py 的编译器选项错误

GCC 修改/自定义目标,在 x86-64 上具有自定义调用约定