I was trying to implement memmove from C into x86 assembly so I wrote:
start:
movb source(%eax), %cl
movb %cl, destination(%eax)
inc %eax
cmp num, %eax
jne start
end:
But this is wrong, why? according to: http://www.cplusplus.com/reference/cstring/memmove/
Copies the values of num bytes from the location pointed by source to the memory block pointed by destination. Copying takes place as if an intermediate buffer were used, allowing the destination and source to overlap.
which my code doesn't support.
How can I fix this without using stack? Note: we can assume that immediately after source destination comes in memory and that num (number of bytes to copy) is far and can't be touched by wrong.
The problem here is about potential overlapping in case
destination - source < size
(that is, bothsource
anddestination
point to the same chunk of data). When this happens, you are in a situation like this:If you start copying from
source
, you will overwrite part of what you are trying to copy (in this example you will overwrite theB
s withA
s), losing the original values, ending up with something like this:When in reality you want this:
You can solve this issue by checking when
destination - source < num
, and copying in reverse in such case (starting witheax = num
).The corresponding assembly would be something like this: