0

我对汇编(NASM)知之甚少,我想使用 SSE4.2 执行字符串操作(是否存在子字符串)。所以我了解了 PCMPESTRI、PCMPISTRM 的工作原理。我被困在中间,即从内存到 xmm 寄存器的数据传输。基本上,我想通过命令行获取输入(例如:./a.out ABCD)并传输到 xmm1 寄存器。通过命令行获取输入可以是任意长度的字符串,即(1 - 大于 16),命令行数据存储后附加 0(即 ABCD\0),我们得到它的起始地址,该地址存在于堆栈中。那么如何使命令行数据对齐到 16 个字节(ABCD\0\0\0\0... 最多 16 个)?

另外我不想使用 brk 系统调用分配内存并将所有命令行数据复制到它,然后传输到 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
...

但它没有用.. 那么我如何通过考虑输入来实现将数据传输到 xmm 寄存器的长度可变(1 - 超过 16)

我应该使用哪个移动指令?

我应该如何解决这种数据移动,其中输入将来自命令行并且它可以是任何长度..?

我的 CPU 信息标志(/proc/cpuinfo)是:sse sse2 ssse2 sse4_1 sse4_2

4

1 回答 1

3

命令行参数在堆栈上,而不是在.data. 对齐.data完全无关紧要。

相关:在 x86 和 x64 上的同一页面内读取缓冲区末尾是否安全?. 你没有对齐你的缓冲区,你只是检查一个 16 字节的加载不会进入一个新的页面(即那个ptr & 4095 <= (4096-16))。

如果你知道这一点,你就不能安全地使用movdqu,不得不退回到另一种策略。pshufb(比如可能加载页面的最后 16 个字节的 16 字节加载,并且可能从滑动窗口中查找控制向量db 0,1,2,3,4,...,-1,-1,-1会将您实际想要的字节打乱到 XMM 寄存器的底部)。

使用 SIMD 处理未对齐的隐式长度字符串通常不方便,因为安全读取的语义取决于一次查看一个字节。(除了利用内存保护具有页面粒度的事实)。

于 2020-03-09T18:38:56.683 回答