I am using nasm on Ubuntu 16.04, and I'm currently trying to recode the C memmove()
function.
Here is my code :
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
I'm calling it this way :
char *str = strdup("Salutation");
printf("%s, %s\n", (char *)memmove(str + 3, str, 5), str);
Expected output is :
Saluton, SalSaluton
But I get :
SalSaon, SalSalSaon
For some reasons, when I get to the fourth character, it goes back to the begining of my string rsi
. My question is why? What am I doing wrong?
PS : The same problem happens every three characters, like if it could not go futher, and had to go back to the first one.
Thanks in advance.
In C there are two functions: memmove
and memcpy
The difference is that memcpy
is a bit faster but it does not allow the destination memory to overlap the source memory.
What you implemented is memcpy
, not memmove
!
Let's implement memcpy
in C (and not in Assembler) to see what is happening:
for(i=0; i<count; i++)
{
destination[i]=source[i];
}
Let's create a char
array with the content "Hello world example"
and perform a memcpy(&(array[6]), &(array[1]), 10);
.
When the loop is executed the first time the letter "w" will be overwritten by an "e" and will be gone forever!
The memmove
function however will check if the source address is before or after the destination address and if the source address is before the destination address it will perfom the loop backwards:
for(i=count-1; i>=0; i--)
By the way: Why didn'd you use the movsb
instruction?