3

我在 Ubuntu 16.04 上使用 nasm,目前正在尝试重新编码 Cmemmove()函数。

这是我的代码:

BITS 64

global memmove

memmove:
        push rbp
        mov rbp, rsp
        xor rcx, rcx

while:
        cmp rcx, rdx
        je end
        mov r10b, byte [rsi + rcx]
        mov byte [rdi + rcx], r10b
        inc rcx
        jmp while

end:
        mov rax, rdi
        leave
        ret

我这样称呼它:

char *str = strdup("Salutation");
printf("%s, %s\n", (char *)memmove(str + 3, str, 5), str);

预期输出为:

Saluton, SalSaluton

但我得到:

SalSaon, SalSalSaon

由于某些原因,当我到达第四个字符时,它会回到我的字符串的开头rsi。我的问题是为什么?我究竟做错了什么?

PS:同样的问题每三个字符发生一次,就像它无法继续前进,不得不回到第一个。

提前致谢。

4

1 回答 1

3

在 C 中有两个函数:memmovememcpy

不同之处在于memcpy它更快一点,但它不允许目标内存与源内存重叠。

你实施的是memcpy,不是memmove

让我们memcpy用 C(而不是 Assembler)实现,看看发生了什么:

for(i=0; i<count; i++)
{
    destination[i]=source[i];
}

让我们创建一个char包含内容的数组"Hello world example"并执行memcpy(&(array[6]), &(array[1]), 10);.

当第一次执行循环时,字母“w”将被“e”覆盖,并且将永远消失!

然而,该memmove函数将检查源地址是在目标地址之前还是之后,如果源地址在目标地址之前,它将向后执行循环:

for(i=count-1; i>=0; i--)

顺便说一句:你为​​什么不使用movsb指令?

于 2017-03-26T17:00:47.740 回答