2017-03-26 2 views
2

zu rekodieren Ich benutze Nasm auf Ubuntu 16.04, und ich versuche derzeit, die C memmove() Funktion zu rekodieren.Ich versuche, memmove in asm

Hier ist mein Code:

char *str = strdup("Salutation"); 
printf("%s, %s\n", (char *)memmove(str + 3, str, 5), str); 

Erwartete Ausgabe lautet::

Saluton, SalSaluton 

Aber ich bekomme:

SalSaon, SalSalSaon 

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 

ich es auf diese Weise bin Aufruf

Aus einigen Gründen, wenn ich zum vierten Zeichen komme, geht es zurück zum Anfang meiner Zeichenfolge rsi. Meine Frage ist warum? Was mache ich falsch?

PS: Das gleiche Problem passiert alle drei Zeichen, als ob es nicht weiter gehen könnte, und musste zurück zum ersten gehen.

Vielen Dank im Voraus.

Antwort

1

In C gibt es zwei Funktionen: memmove und memcpy

Der Unterschied besteht darin, dass memcpy etwas schneller ist, aber es ist nicht der Zielspeicher der Quellspeicher zu überlappen.

Was Sie implementiert haben, ist memcpy, nicht memmove!

der memcpy in C (und nicht in Assembler) Lassen Sie implementieren, um zu sehen, was passiert:

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

Lassen Sie uns erstellen char Array mit dem Inhalt "Hello world example" und führen Sie eine memcpy(&(array[6]), &(array[1]), 10);.

Wenn die Schleife das erste Mal ausgeführt wird, wird der Buchstabe "w" durch ein "e" überschrieben und wird für immer verschwinden!

Die memmove Funktion wird jedoch prüfen, ob die Adressenquelle vor oder nach der Zieladresse und wenn die Adresse Quelle vor der Zieladresse ist, wird es die Schleife perfom rückwärts:

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

By the way: Warum hast du den movsb Befehl benutzt?