Sie klar ein Puffer, um es durch das Schreiben.
Offensichtlich ist ein Speicherort im Speicher nie wirklich leer, daher bedeutet das Löschen eines Puffers, dass er mit Nullen gefüllt wird.
Es gibt nichts, was Sie davon abhält, es mit 0xCAFEBABE
Hexadezimalwerten zu füllen, aber Nullen ist die Standardkonvention.
mov dword ptr [buffer],0
mov dword ptr [buffer+4],0
mov ... +8],0
....
Offensichtlich ist dies eine alberne Art, einen Puffer zu löschen. Wenn der Puffer 40.000 Byte wäre, würden Sie 10.000 Anweisungen benötigen; möglich, aber verschwenderisch.
Stattdessen schreiben Sie eine Schleife und verwenden Sie einen Zähler, um zu verfolgen, was Sie bisher geschrieben haben.
mov ecx,10000 //10000 x 4 = 40.000 bytes
lea edx,[buffer] //point edx to the start of the block to be cleared.
xor eax,eax //xor reg,reg is the same as mov reg,0, but faster.
@loop:
mov [edx+ecx*4],eax //fill the buffer starting at the end.
dec ecx //decrease the counter; also moving the destination.
jnz @loop //if ecx <> 0 (Non-Zero) then repeat.
ret //we are done, return.
ecx
erfüllt zwei Funktionen als Zähler und als Zeiger in den Puffer.
Beachten Sie, dass xor eax,eax
die Standardmethode ist, ein Register auf Null zu setzen. Es ist sowohl kürzer als mov eax,0
und schneller, weil die CPU fest verdrahtet ist, um der ersteren Anweisung bevorzugte Behandlung zu geben.
Es gibt jedoch eine noch kürzere Möglichkeit, dies zu tun.
x86 hat sogenannte String-Anweisungen, die eine rep
(repeat) prefix akzeptieren.
Wenn so vorangestellt wird, wird die Anweisung ecx
mal ausgeführt.
push edi //on Windows edi is non-volatile (callee-save), so save it.
lea edi,[buffer] //edi is the start of the buffer.
xor eax,eax //fill the buffer with zeros.
mov ecx,10000
rep stosd //store string with 10000 dwords = 40000 bytes.
pop edi //restore edi to its previous value.
ret //return.
stosd
(s ̲ t ̲ o ̲ re s ̲ Tring pro d ̲ Wort) verwendet edi
als D ̲ estination und ecx
als C ̲ ounter eax
und als Quelle.
Beachten Sie, dass stosd
eine komplexe Anweisung ist. Moderne x86-CPUs arbeiten schneller mit einfachen Anweisungen und oft funktioniert eine optimierte (!) Version des zweiten Codeausschnitts schneller als eine einfache Verwendung von rep stosd
.
rep stosd
verschiebt sich standardmäßig unter Windows/Linux. Sie können die CPU so einrichten, dass sie rückwärts läuft, aber dann müssen Sie die Richtungseinstellung danach wiederherstellen.
Unter Windows eax
, ecx
und edx
sind flüchtig und können nach Belieben verändert werden. Alle anderen Register müssen zwischen den Anrufen erhalten bleiben.
nicht anders als in jeder anderen Sprache. –
Sie suchen nach 'rep stosb'. Können Sie den gleichen Puffer nicht erneut verwenden, ohne ihn zu löschen? Wenn Sie den vorherigen Inhalt bereits verwenden, warum müssen Sie ihn dann löschen? –
@DanielKamilKozar Ich muss den Inhalt des Puffers in eine Datei schreiben, ich denke nur, wenn ich es mehrmals benutze, ohne es zu löschen, kann ich es nicht füllen und einen Überlauf bekommen? – JamesFred