内联汇编中的 vpcmpeqb

Posted

技术标签:

【中文标题】内联汇编中的 vpcmpeqb【英文标题】:vpcmpeqb in inline assembly 【发布时间】:2020-04-07 13:57:28 【问题描述】:

目前我正在尝试从使用 NASM 转向在 c 中使用内联汇编,因为这将使将来的链接变得更加容易(尤其是内联)。但是,我无法让我的矢量指令播放得很好。在英特尔组装中,我能够做到以下几点:

vpcmpeqb    ymm0, [rdi]

这将从rdi 读取32 个字节,与ymm0 比较并标记相等的字节。使用 AT&T,我尝试在 c inline asm 中执行以下操作,但它不起作用,它一直抱怨操作数大小不匹配(其中 %1 是输入 as"r"(s)):

vpcmpeqb    %%ymm0, %%ymm0, (%1)

我正在编译 gcc 版本9.2.1

【问题讨论】:

AT&T 语法将目的地放在最后。出于同样的原因,NASM vcmpeqb [rdi], ymm0, ymm0 不合法。您可以使用objdump -d 来获取 AT&T 对您在 NASM 中编写的内容的反汇编,以帮助学习语法。 但是千万不要在 C 中使用内联 asm 进行手动矢量化;使用 __m256 v = _mm256_cmpeq_epi8 内在函数。 gcc.gnu.org/wiki/DontUseInlineAsm 您通常可以让编译器生成与您可以手动编写的一样好的 asm,而且您不必担心 GNU C 内联 asm,这非常困难使用。例如除非您在该 asm 语句中有 "memory" clobber 或虚拟 "m" 输入,否则在寄存器中请求指针是不安全的。 How can I indicate that the memory *pointed* to by an inline ASM argument may be used? @PeterCordes 谢谢你成功了!我也会注意内联汇编,但内在函数在 IMO 中是如此的考验,它们甚至比内联汇编更棘手。 @codam_hsmits 这应该是查看software.intel.com/sites/landingpage/IntrinsicsGuide 的第一页。您可以搜索 asm-mnemonics,也可以“浏览”不同指令的类别。您还可以查看“英特尔® 64 和 IA-32 架构软件开发人员手册”,此处提供了不错的(非官方)在线副本:felixcloutier.com/x86 ***.com/tags/sse/info 有几个链接,包括codeproject.com/Articles/874396/… 这是一个使用内在函数的介绍教程。在我将它添加到标签 wiki 时,我认为它还不错。既然您已经了解 asm,只需了解像 _mm_add_epi32 这样的内部函数对应于像 paddd 这样的 asm 指令,就像 + 运算符对应于 add 一样 - 编译器可以优化以不同的方式执行。另请参阅 this re: what __m128i really is 和严格别名。 【参考方案1】:

AT&T 对操作数使用不同的顺序。要解决您的问题,您应该使用

vpcmpeqb    (%1), %%ymm0, %%ymm0

此外,请阅读对话下方的主题,了解有关此主题的更多信息。

【讨论】:

以上是关于内联汇编中的 vpcmpeqb的主要内容,如果未能解决你的问题,请参考以下文章

gcc 内联汇编中的 min

MSVC 内联汇编中的“拒绝”是啥意思

GCC 内联汇编中的标签

GCC内联汇编中的C数组?

为啥包装在函数中的 GAS 内联汇编为调用者生成的指令与纯汇编函数不同

简单 g++ 内联汇编程序中的错误