我对汇编(NASM(知之甚少,我想使用SSE4.2执行字符串操作(是否存在子字符串(。所以我学会了PCMPESTRI,PCMPISTRM是如何工作的。我被困在中间,即从内存到xmm寄存器的数据传输。基本上,我想通过命令行(例如./a.out ABCD(获取输入,并将其传输到xmm1寄存器。通过命令行进行输入可以是任何长度的字符串,即(1-大于16(,命令行数据存储时附加0(即ABCD\0(,我们得到它的起始地址,该地址存在于堆栈中。那么,如何使命令行数据对齐到16个字节(ABCD\0\0\0\0…最多16个(呢?
此外,我不想使用brk系统调用来分配内存,并将所有的comandline数据复制到其中,然后传输到xmm1寄存器。(因为我想一次性完成子字符串检查,而不是将所有数据移动到新分配的内存中,然后复制所有内容……这可能会增加执行时间(
我试着这样做:-
section .data
align 16 ; I thought that command line data is stored in data section and may align to 16. :-(
...
section .bss
...
section .text
...
但它没有起作用。。那么,我如何通过考虑输入可以是可变长度的(1-大于16(来实现将数据传输到xmm寄存器
我应该使用哪种移动指令?
我应该如何解决这个数据移动,输入将来自命令行,并且它可以是任何长度。。?
我的CPU信息标志(/proc/cpuinfo(是:sse sse2 ssse2 sse4_1 sse4_2
命令行参数在堆栈上,而不是在.data
中。对齐.data
是完全无关的。
相关:在x86和x64上,在同一页内读取超过缓冲区末尾是否安全?。您不对齐缓冲区,只需检查16字节的加载是否不会进入新页面(即ptr & 4095 <= (4096-16)
(。
如果不知道这一点,那么就无法安全地使用movdqu
,而不得不求助于另一种策略。(就像加载页面最后16个字节的16字节加载一样,也可以从db 0,1,2,3,4,...,-1,-1,-1
的滑动窗口中查找pshufb
控制向量,该向量会将您实际想要的字节混洗到XMM寄存器的底部(。
使用SIMD处理未对齐的隐式长度字符串通常是不方便的,因为安全读取的语义取决于一次查找一个字节。(除了利用内存保护具有页面粒度这一事实之外(。