The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: Nilrem on February 25, 2005, 04:43:33 PM

Title: Emptying a string?
Post by: Nilrem on February 25, 2005, 04:43:33 PM
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.
Title: Re: Emptying a string?
Post by: mariø on February 25, 2005, 04:52:26 PM
why not


mov byte ptr[var],NULL
Title: Re: Emptying a string?
Post by: AeroASM on February 25, 2005, 06:45:45 PM
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?
Title: Re: Emptying a string?
Post by: P1 on February 25, 2005, 11:08:41 PM
If you are re-using the string space it's best to clear it.

invoke RtlZeroMemory,OFFSET szErrorMessage,SIZEOF szErrorMessage

Regards,  P1  :8)
Title: Re: Emptying a string?
Post by: Mark Jones on February 26, 2005, 01:24:18 AM
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:   
Title: Re: Emptying a string?
Post by: raymond on February 26, 2005, 02:31:44 AM
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
Title: Re: Emptying a string?
Post by: hutch-- on February 26, 2005, 04:13:04 AM
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

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
Title: Re: Emptying a string?
Post by: Jimg on February 26, 2005, 05:40:06 PM
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?
Title: Re: Emptying a string?
Post by: The Dude of Dudes on February 26, 2005, 11:43:11 PM
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


Title: Re: Emptying a string?
Post by: hutch-- on February 27, 2005, 12:49:46 AM
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.
Title: Re: Emptying a string?
Post by: Jimg on February 27, 2005, 02:00:24 AM
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.
Title: Re: Emptying a string?
Post by: Nilrem on March 02, 2005, 01:04:31 PM
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
Title: Re: Emptying a string?
Post by: pro3carp3 on March 02, 2005, 02:27:24 PM
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

Title: Re: Emptying a string?
Post by: Nilrem on March 07, 2005, 01:51:06 PM
Used RtlZeroMemory because I am reusing the same string, worked perfectly thanks.
Title: Re: Emptying a string?
Post by: GregL on March 07, 2005, 07:27:12 PM
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

Title: Re: Emptying a string?
Post by: pro3carp3 on March 07, 2005, 08:17:03 PM
Oops... :red

Thank you Greg.