News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Emptying a string?

Started by Nilrem, February 25, 2005, 04:43:33 PM

Previous topic - Next topic

Nilrem

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.

mariø

why not


mov byte ptr[var],NULL

AeroASM

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?

P1

If you are re-using the string space it's best to clear it.

invoke RtlZeroMemory,OFFSET szErrorMessage,SIZEOF szErrorMessage

Regards,  P1  :8)

Mark Jones

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:   
"To deny our impulses... foolish; to revel in them, chaos." MCJ 2003.08

raymond

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
When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com

hutch--

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

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

Jimg

#7
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?

The Dude of Dudes

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



hutch--

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.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

Jimg

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.

Nilrem

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

pro3carp3

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

LGC

Nilrem

Used RtlZeroMemory because I am reusing the same string, worked perfectly thanks.

GregL

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