assembly - 为什么 xmm 逻辑移位不起作用?

标签 assembly nasm intel simd mmx

我在xmm1寄存器加载了一些内容,假设它可以被视为

xmm1 = | bgra | bgra | bgra | bgra | (each one a dw)

现在,我想将每个双字逻辑右移 1 个字节,最终结果如下:

xmm1 = | 0bgr | 0bgr | 0bgr | 0bgr | (each one a dw)

我在 intel doc 找到我可能正在寻找函数“psrld”: enter image description here

但是,它并没有像我预期的那样工作,因为一开始 xmm1 的值是

xmm1           {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x37, 0x51, 0x9e, 0x0, 0x3e, 0x58, 0xa5, 0x0, 0x3e, 0x5a, 0xa7, 0x0, 0x4a, 0x66, 0xb3, 0x0}, v8_int16 = {0x5137, 0x9e, 0x583e, 0xa5, 0x5a3e, 0xa7, 0x664a, 0xb3}, v4_int32 = {0x9e5137, 0xa5583e, 0xa75a3e, 0xb3664a}, v2_int64 = {0xa5583e009e5137, 0xb3664a00a75a3e}, uint128 = 0x00b3664a00a75a3e00a5583e009e5137}

然后,应用psrld xmm1, 1后,xmm1的值为

xmm1           {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x9b, 0x28, 0x4f, 0x0, 0x1f, 0xac, 0x52, 0x0, 0x1f, 0xad, 0x53, 0x0, 0x25, 0xb3, 0x59, 0x0}, v8_int16 = {0x289b, 0x4f, 0xac1f, 0x52, 0xad1f, 0x53, 0xb325, 0x59}, v4_int32 = {0x4f289b, 0x52ac1f, 0x53ad1f, 0x59b325}, v2_int64 = {0x52ac1f004f289b, 0x59b3250053ad1f}, uint128 = 0x0059b3250053ad1f0052ac1f004f289b}

这不是我想做的。我哪里错了?完成此任务的正确方法是什么?

最佳答案

示例的输出是正确的,因此,例如,第一个 v4_int32 是 0x9e5137 =

100111100101000100110111

psrld xmm1, 1之后是0x4f289b =

010011110010100010011011

因此每个 uint32 都右移一位。

<小时/>

您的尝试是正确的 - 除了一点:
您向右移动了一位,而不是您想要的一个字节。所以使用

psrld xmm1, 8   ; shift right by one byte

而不是

psrld xmm1, 1   ; shift right by one bit

应该可以解决你的问题。

关于assembly - 为什么 xmm 逻辑移位不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49948462/

相关文章:

arrays - 在 MIPS 中仅在运行时已知的数组大小

assembly - TASM 程序输出垃圾并可能在退出时挂起

c - NASM 与 C 混合

performance - rdmsr 时序是否取决于寄存器读取?

ios - 使用 clang 集成汇编器为 iOS 5.1 编译 NEON 时出错

assembly - 递归过程

arrays - 从 gdb 中的 .bss 打印 "array"

assembly - nasm - 错误 : label or instruction expected at the start of line

c++ - 这个时钟滴答适用于 Intel i3 吗?

c - 最小 SIMD vector 宽度数据类型