使用汇编在字符串中移位字符的最佳方法是什么?

Zey*_*man 0 assembly irvine32

我问的是使用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
Run Code Online (Sandbox Code Playgroud)

Pet*_*des 5

在像您的示例一样的4字节字符串的特殊情况下,用于rol dword ptr [arr], 8执行您描述的旋转.

(请记住,x86是little-endian,因此在多字节操作数内左移会将字节移动到更高的地址).

在非特殊情况下,只需memmove()使用普通的复制循环实现一个移位字节,然后复制必须环绕的字节.(您可能希望在进入复制循环之前加载包裹的字节,因此您可以覆盖存储它的位置.)


执行此操作(性能)的最佳方法可能是SSE movups. rep movsb具有较高的启动开销,并且在未对齐的数据上较慢.并且可能不适合重叠的目的地,但我不记得看到提到的.

如果那不是你所说的"最好",那就更具体,说"最容易理解"或者别的什么.

  • `MOVS`被设计*通过添加DF来处理重叠数据,所以在OP ABCD的情况下 - > DABC他必须将`esi/edi`设置为缓冲区的结尾,并且`STD`来制作`MOVS `倒退.在80386次高度优化的'memmove(medium/large_size)`包括将少量字节移动到4B对齐的序言,然后是`MOVSD`来完成这项工作,以及结束剩余的%4字节的结尾.此外,它有两个分支,当然,取决于重叠方向. (2认同)