内联汇编中的 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 语法将目的地放在最后。出于同样的原因,NASMvcmpeqb [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的主要内容,如果未能解决你的问题,请参考以下文章