如何复制每个双字的最后一个字节?

Posted

技术标签:

【中文标题】如何复制每个双字的最后一个字节?【英文标题】:How to duplicate last byte of each double-word? 【发布时间】:2019-01-03 22:25:40 【问题描述】:

我使用SSE,我想将每个双字的最后一个字节复制4次XMM0,但我不知道该怎么做! (也许有(未)包装?)

为了说明,我想做 this.

感谢您的帮助!

【问题讨论】:

哪些版本的 SSE 可用? SSSE3 会让这一切变得简单 如果没有pshufb,您可以使用set1_epi32(0x000000ff) 进行屏蔽,然后使用shift + OR。然后pshuflw / pshufhw 广播字节。这可能比屏蔽 + packusdw / wb 到字和字节,然后 punpcklbw / wd 回到双字更有效。 【参考方案1】:

您可以像这样使用 SSSE3 命令PSHUFB 执行此操作(MASM 32 位程序集)

.data 
  align 16
  mask  db 0,0,0,0, 4,4,4,4, 8,8,8,8, 12,12,12,12
.code
  ; value in XMM0                  ; 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
  pshufb xmm0, xmmword ptr [mask]  ; 12 12 12 12 08 08 08 08 04 04 04 04 00 00 00 00

输出似乎与掩码匹配是巧合。 我目前无法对此进行测试,掩码字节的顺序可能会颠倒。但你应该明白了。

无论如何:注意对齐,因为

当源操作数是 128 位内存操作数时,操作数必须在 16 字节边界上对齐,否则会产生通用保护异常 (#GP)。

【讨论】:

你的面具倒退(在我编辑之前)。该顺序对于_mm_set_epi8 是正确的,它采用高..低顺序的 args。但是低元素(索引 0)是从内存中的最低地址加载/存储的,因此这也会颠倒寄存器中双字的顺序。您评论中的符号是英特尔的正常排序,与内存顺序相反(C 数组初始化程序和 asm db)。请参阅 Convention for displaying vector registers 了解有关大与小“端序”矢量符号的更多讨论。 您通常会在.rdata(Windows 上的只读数据)中放置一个向量常量,而不是.data。 (或 .rodata 在非 Windows 上。)

以上是关于如何复制每个双字的最后一个字节?的主要内容,如果未能解决你的问题,请参考以下文章

存储到堆栈地址的双字是不是会影响地址+0..3 或地址-0..3 处的字节?

字节对齐

如何在python中将纯文本转换为分段块(字节)? [复制]

第三章知识总结

80x86汇编

汇编实验第六到八章总结