从ESI复制到缓冲区到EDI

时间:2017-09-27 19:55:08

标签: assembly x86 nasm

我一直在努力解决如何通过缓冲区进行内存复制的问题。

我的功能参数是:void* dest, void* src, size_t length

我设置了我的功能:

push ebp
mov ebp, esp
push edi
push esi
push ebx

mov edi, [ebp+0x8] ; this is dest
mov esi, [ebp+0xc] ; this is src
mov ecx, [ebp+0x10] ; this is length

我对下一步做什么感到有点失落。我知道我需要创建一个缓冲区,因为我可能有重叠的内存,但我不确定如何在我的函数中设置缓冲区。

一旦我做了,我想下面的代码看起来像(假设ebx作为缓冲区):

mov ebx, [esi+4*ecx]
mov edi, [ebx]

pop edi
pop esi
pop ebx
mov esp, ebp
pop ebp

提前致谢!

编辑:为了澄清,我在这里发表了一条评论:基本上,我想把esi中存储的数据移到edi,但我也想避免esiedi之间可能存在内存重叠的情况。我相信,使用类似缓冲区的东西可以实现这个目标(我使用的术语是错误的吗?)。

1 个答案:

答案 0 :(得分:2)

这里有两件事。首先,通常通过切换复制的方向来处理重叠存储器。你应该首先说服自己无论这两个区域如何重叠,要么从每个块的最低地址开始,要么从源复制到目标,为每个字节递增指针;或者从每个块中的最高地址开始并同样复制,但随后递减指针将起作用。

使用中间缓冲区要么需要将副本平铺到固定大小的缓冲区,这仍然需要操纵方向,或者调用例如malloc,它大多只是很慢,但也需要弄清楚如何从汇编中调用函数。

首先,我建议用C / C ++或类似方法编写有条件的方向和两个循环。 (有指针的语言有帮助。)I.e。在C中编写自己的memmove副本。

此时,您需要将if语句,循环和从源复制到目标,转换为汇编。这一切都非常简单,在评论中有一些建议如何使用x86指令为你做一个计数循环。 (请注意,如果使用内置支持,您需要了解x86方向标志,例如CLD和STD指令。我首先要做的很长,然后转到使用REP *支持。)

解决此问题的一种方法是编写C / C ++代码并将汇编输出标志用于编译器(例如,在大多数UNIX系统上使用-S)。