In C I can just empty a string via:
strcpy (var, "")
However in asm I am not sure how to do this since it says it is an error when trying to copy an empty string.
why not
mov byte ptr[var],NULL
What mario's code does is put a zero byte at the beginning. Do you remember from another thread that strings are terminated with 0 or NULL?
If you are re-using the string space it's best to clear it.
invoke RtlZeroMemory,OFFSET szErrorMessage,SIZEOF szErrorMessage
Regards, P1 :8)
Hi P1! Hmm, couldn't the same thing be done with this?
mov eax, MyVarToErase
mov ecx, MyNumBytesToClear
loopit:
mov [eax], 00h ; put a null in the string value EAX at position EAX+count
inc eax ; increment string byte position (EAX+n)
dec ecx ; decrement number of bytes left to clear
cmp ecx, 0 ; has counter expired?
je done ; if so, break loop
jmp loopit ; else start over and clear another byte
done:
Quotemov eax, MyVarToErase
This would all depend on which assembler syntax you are using. With some assemblers, EAX would get the value of the dword located at the MyVarToErase address, and your code would probably crash if the assembler does not first complain about invalid size. With other assemblers, EAX would effectively get the address of the MyVarToErase variable.
dec ecx
That instruction modifies the Z flag based on the result. It is thus redundant to compare ECX to 0. You could simply use immediately after it:
jnz loopit
IMHO, when using null-terminated strings, rezeroing the first byte is sufficient and rezeroing the entire allocated area for the string would be overkill.
Raymond
I think Mark had the right idea, here is a quicky that is easy enough to follow. This little algo clears the buffer but if the buffer is for a zero terminated string, setting the first byte to zero is more efficient.
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
align 4
zero_it proc lpmem:DWORD,cnt:DWORD
mov ecx, lpmem ; address in ECX
mov edx, cnt ; Count in EDX
xor eax, eax ; set EAX to zero to zero AL
@@:
mov [ecx+edx], al ; zero byte at address in ECX
sub edx, 1 ; decrement EDX
jns @B ; loop back if > -1
ret
zero_it endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
Hutch-
I'm going to ask a dumb question here, please be patient...
What ever happened to rep stosb? I tested the following:
xzero_it proc lpmem:DWORD,cnt:DWORD
mov edi, lpmem
mov ecx, cnt
inc ecx
cld
xor eax, eax ; set EAX to zero to zero AL
rep stosb
ret
xzero_it endp
on my Athlon, using a string 256 bytes long, yours averaged 538 clocks, this one averaged 288 clocks and it's simpler. Am I missing something basic here?
QuoteHutch-
I'm going to ask a dumb question here, please be patient...
What ever happened to rep stosb? I tested the following:
Code:
xzero_it proc lpmem:DWORD,cnt:DWORD
mov edi, lpmem
mov ecx, cnt
inc ecx
cld
xor eax, eax ; set EAX to zero to zero AL
rep stosb
ret
xzero_it endp
on my Athlon, using a string 256 bytes long, yours averaged 538 clocks, this one averaged 288 clocks and it's simpler. Am I missing something basic here?
Try this instead:
Code:
xzero_it proc lpmem:DWORD,cnt:DWORD
mov edi, lpmem
mov ecx, cnt
shr ecx, 2 ;<----- div by 4 (sizeof dword)
;inc ecx <------ not necessary
cld
xor eax, eax ; set EAX to zero
rep stosd ;<------- instead of stosb, stores a dword every iteration and adds 4 to edi
ret
xzero_it endp
Guys,
The fast way to do it is an unrolled DWORD loop but the idea of posting a simple algo was so it could easily be understood. REP STOSB works fine, REP STOSD works better but you must clean up uneven tail end. Once the member is familiar with how its done, he will pick whichever way suits his coding style.
Thank you Hutch. I just thought there might be some reason NOT to use rep stosb because it ran slow on pentium 4's or something. Similar to using add 1 rather than inc.
Sorry I've been busy lately so haven't looked. Thanks for the replies extremely helpful, and yes AeroAsm I remember now but I never saw your tuts intended for me (I did pm you about it). Thanks guys, I am getting better at asm and it thanks to you guys. 8-) I love this place. :U
My contribution:
(air code)
xzero_it proc lpmem:DWORD, cnt:DWORD
cld
xor eax, eax
mov edi, lpmem
mov ecx, cnt
mov edx, ecx
shr ecx, 2d
rep stosd
mov ecx, edx
and 3d
rep stosb
ret
xzero_it endp
Used RtlZeroMemory because I am reusing the same string, worked perfectly thanks.
pro3carp3,
Correction. You did say it was "air code". After the correction the procedure does the job just fine.
xzero_it proc lpmem:DWORD, cnt:DWORD
cld
xor eax, eax
mov edi, lpmem
mov ecx, cnt
mov edx, ecx
shr ecx, 2d
rep stosd
mov ecx, edx
and ecx, 3d ; <-- correction
rep stosb
ret
xzero_it endp
Oops... :red
Thank you Greg.