请SSE/SSE2熟悉的前辈指点下指令,比较简单

「已注销」 「已注销」 墨衍会员 · AI 创作全网分发 墨衍智能分发 通过墨衍一键同步至各平台 可同步平台 CSDN微信公众号微博知乎掘金百家号博客园抖音小红书 你的文章也可以这样分发 墨衍会员 ¥399起/年,写一次发全网 我也要 + 加入社区
我刚学用汇编来写SSE/2相关操作的东西,所以对指令的运用相当不熟练,写一条都要查好久。。。

SSE里有这么个指令:MASKMOVQ,而SSE2又加了这个指令:MASKMOVDQU;
这俩用法差不多,只不过一个针对MMX寄存器,一个针对XMM寄存器,位数不同而已,都是:

指令 源数据寄存器, 移位表寄存器

这样的格式,实际上指令作用是把 64或128位的源数据拷贝到对应位数的指针里,但命令里没有指针,指针要在edi里面提供;
而之所以特殊是这个指令不是移动全部64或128位数据,只移动指定的字节,所以就有了第二个操作数:移位表。
它是跟源数据相同位数的寄存器,比如64位就是mm(可以指定最多8个字节)、128位就是xmm(可以指定最多16个字节);
当然一般没人会在移动整个(8或16)字节时来这么复杂的搞,用其他完整移动的指令就好了。。

而移位表的表示法是取每个字节的最高位,比如最低位[0-7]的字节,bit7 = 1 表示复制,bit7 = 0 表示不复制,用十进制说就是第一个字节是128就表示复制;而32678就表示复制第二个字节 bit15 = 1;以此类推。。。

以上是我读手册里自己总结的,应该是这个作用把???
而它能用在很多复杂的情况下,不但移动整个数据高位几个字节,低位几个字节可以用,甚至随意自由的移动中间或相间隔的几个字节都可以,但我现在还没要求这么复杂。

我现在只需要用在从低位开始拷贝多少(1-7,或1-15)个字节就行,但要想实现这个,就要首先把移位表这个寄存器填充好,说了一大堆终于说到我要问的了,我想问下如何构造这个移位表啊???
准确的说,如何快速构造移位表???因为如果是使用通用寄存器与MMX/XMM寄存器交叉循环一点点的算,一个个字节为赋值的话(就是最傻瓜的原理),我肯定是会的。。。
但我觉得肯定有比较简单快速的方法的,甚至只通过MMX/XMM寄存器相关的位运算等指令左右移动啥的就可以实现,所以我说我的问题实际上并不复杂,但是对于32位数的位运算我脑子的反应就很不灵活,只会照搬照抄,别说一下子到了128位了。。。

上面移位表的构造原理说了是根据每个字节的最高位,而我自己感觉为了快速生成移位表,要复制的那个字节对应的其他7个位都是1也行,这样应该会构造的更快吧,比如255表示复制第一个字节,65536表示复制第二个字节……

这样的话其实我自己想了个最基本的简单方法,拿128位寄存器举例:
将一个xmm先置0,再 -1,这样128个位都是1咯,
然后 先 pslldq xmm, (16-n);
接着 再 psrldq xmm, (16-n);
其中 n = 要从低位开始复制的字节数,是不是就会把右边不复制的那些位弄成0了???
我不知道这样想对不对,也不知道这么算是不是比较快。。。
因为连最基本的我都有点诧异:
在x86汇编里,我们将一个32位寄存器每一位全都搞成1,也就是说 reg32 = -1 呗,这样可以:
mov eax, -1;
或者专业一点:
xor eax, eax;
dec eax
都可以,但是这个xmm寄存器怎么弄成128位全是1啊?莫非是:
xor eax, eax
inc eax
movd xmm1, eax
pxor xmm0, xmm0
psubq xmm0, xmm1
movdqa xmm1, xmm0
punpckldq xmm0, xmm1
哈哈,我觉得有点扯淡了,这样确实能把128位全部置1,但我觉得这肯定不会是构造移位表应该采用的方法,所以越想越糊涂,只好来请教前辈了。。。

教教我,如何能快速填充好移位表,用1-7位 或 1-15位都行,我明白套路即可。。。多谢!
...全文
评论 14
收藏 已收藏
分享
返回顶部
「已注销」
汇编语言 21,500 成员 41,619 内容