我一直在努力解决如何通过缓冲区进行内存复制的问题。
我的功能参数是: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
,但我也想避免esi
和edi
之间可能存在内存重叠的情况。我相信,使用类似缓冲区的东西可以实现这个目标(我使用的术语是错误的吗?)。
答案 0 :(得分:2)
这里有两件事。首先,通常通过切换复制的方向来处理重叠存储器。你应该首先说服自己无论这两个区域如何重叠,要么从每个块的最低地址开始,要么从源复制到目标,为每个字节递增指针;或者从每个块中的最高地址开始并同样复制,但随后递减指针将起作用。
使用中间缓冲区要么需要将副本平铺到固定大小的缓冲区,这仍然需要操纵方向,或者调用例如malloc,它大多只是很慢,但也需要弄清楚如何从汇编中调用函数。
首先,我建议用C / C ++或类似方法编写有条件的方向和两个循环。 (有指针的语言有帮助。)I.e。在C中编写自己的memmove副本。
此时,您需要将if语句,循环和从源复制到目标,转换为汇编。这一切都非常简单,在评论中有一些建议如何使用x86指令为你做一个计数循环。 (请注意,如果使用内置支持,您需要了解x86方向标志,例如CLD和STD指令。我首先要做的很长,然后转到使用REP *支持。)
解决此问题的一种方法是编写C / C ++代码并将汇编输出标志用于编译器(例如,在大多数UNIX系统上使用-S)。