assembly - 尝试在 asm 中重新编码 memmove

标签 assembly nasm memmove

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

这是我的代码:

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:每三个字符就会出现同样的问题,好像不能再继续了,不得不回到第一个。

提前致谢。

最佳答案

在 C 中有两个函数:memmovememcpy

区别在于memcpy 速度稍快,但它不允许目标内存与源内存重叠。

你实现的是memcpy,不是memmove!

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

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

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

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

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

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

顺便问一下:你为什么不使用 movsb 指令?

关于assembly - 尝试在 asm 中重新编码 memmove,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43030635/

相关文章:

assembly - NASM:如何正确访问 ssd 驱动器?

linux - 如何在nasm中读取并显示文本文件的内容?

c - linux中的signal,int 0x80是谁调用的?

assembly - gpasm 抛出 "Processor-header file mismatch"和 "Processor type is undefined"错误

linux - 需要一些关于 NASM 循环的建议

vector - Rust 中向量的元素如何左移?

c - C 中的 trim 函数是否需要 memmove?

c - memcpy() 与 memmove()

assembly - Bochs GDT 段限制以十六进制形式左移 3 次,并添加 0xFFF。这是正常的吗?

string - 查找输入字符串中的子字符串