使用汇编在字符串中移动字符的最佳方法是什么?
What's the best way to shift characters in a string using assembly?
我问的是使用 Irvine 库在 x86 程序集中将字符串中的字符向右或向左移动的最佳方法是什么。
有一个例子:
ABCD --> DABC 等等
我写了这段代码,但它给了我错误的结果。
r1:
push ecx
mov ecx,lengthof arr
mov al,[esi+lengthof arr]
mov bl,[esi]
mov [esi],al
mov [esi+1],bl
inc esi
innr1:
mov al,[esi]
mov bl,[esi+1]
mov [esi],al
inc esi
loop innr1
pop ecx
loop r1
在像您的示例这样的 4 字节字符串的特殊情况下,使用 rol dword ptr [arr], 8
执行您描述的旋转。
(请记住 x86 是小端字节序的,因此在多字节操作数中左移将字节移动到更高地址)。
在非特殊情况下,只需实现一个 memmove()
和一个普通的复制循环来转移字节,然后复制必须环绕的字节。 (您可能想在进入复制循环之前加载环绕的字节,这样您就可以覆盖它的存储位置。)
执行此操作(为了提高性能)的最佳方法可能是使用 SSE movups
。 rep movsb
具有高启动开销,并且在未对齐的数据上速度较慢。并且可能不适用于重叠的目的地,但我不记得看到过提到过的内容。
如果 "best" 不是您的意思,请更具体地说 "easiest to understand" 或其他内容。
我问的是使用 Irvine 库在 x86 程序集中将字符串中的字符向右或向左移动的最佳方法是什么。 有一个例子: ABCD --> DABC 等等
我写了这段代码,但它给了我错误的结果。
r1:
push ecx
mov ecx,lengthof arr
mov al,[esi+lengthof arr]
mov bl,[esi]
mov [esi],al
mov [esi+1],bl
inc esi
innr1:
mov al,[esi]
mov bl,[esi+1]
mov [esi],al
inc esi
loop innr1
pop ecx
loop r1
在像您的示例这样的 4 字节字符串的特殊情况下,使用 rol dword ptr [arr], 8
执行您描述的旋转。
(请记住 x86 是小端字节序的,因此在多字节操作数中左移将字节移动到更高地址)。
在非特殊情况下,只需实现一个 memmove()
和一个普通的复制循环来转移字节,然后复制必须环绕的字节。 (您可能想在进入复制循环之前加载环绕的字节,这样您就可以覆盖它的存储位置。)
执行此操作(为了提高性能)的最佳方法可能是使用 SSE movups
。 rep movsb
具有高启动开销,并且在未对齐的数据上速度较慢。并且可能不适用于重叠的目的地,但我不记得看到过提到过的内容。
如果 "best" 不是您的意思,请更具体地说 "easiest to understand" 或其他内容。