我对程序集(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
完全不相关。
相关:Is it safe to read past the end of a buffer within the same page on x86 and x64?。您无需对齐缓冲区,只需检查16字节的负载就不会越过新页面(即ptr & 4095 <= (4096-16)
)。
如果您不知道知道这一点,您将无法安全地使用movdqu
,而不得不使用其他策略。 (例如,可能有16个字节的加载会加载页面的最后16个字节,并且可能会从pshufb
的滑动窗口中查找db 0,1,2,3,4,...,-1,-1,-1
控制向量,这会将您实际想要的字节拖移到XMM的底部)注册)。
使用SIMD处理未对齐的隐含长度字符串通常很不方便,因为安全读取内容的语义取决于一次查找一个字节。 (除了利用内存保护具有页面粒度这一事实之外)。