Title: About LOCAL string Post by: stbfish on September 16, 2009, 06:08:02 AM LOCAL szDir[124]:BYTE how to initialize it to all 0? like this szBuffer db 124 dup(0) when i define a LOCAL Var, what is the default value inside? Title: Re: About LOCAL string Post by: BlackVortex on September 16, 2009, 06:47:05 AM Well, default value is zero !
Right ? Title: Re: About LOCAL string Post by: sinsi on September 16, 2009, 07:02:02 AM Because locals are on the stack they could be any value. You will need to zero it yourself - RtlZeroMemory I think will work here.
Title: Re: About LOCAL string Post by: ecube on September 16, 2009, 09:29:36 AM sinsi is right, and this is important to remember as it could have unexpected results for your program. I always rtlzeromemory my local buffers before using it, unless I Use GlobalAlloc or similar
Code: myproc proc local mybuf[1024]:BYTE invoke RtlZeroMemory,addr mybuf,1024 ;now save to use ret myproc endp a global buffer will always be initalized to zero though e.g mygbuf byte 1024 dup(?) also when it comes to buffer sizes I usually try and stick with 1 evenly divisible by 4,since the 32bit processor reads everything in dwords, you could also use align 4, align 8 etc before it... to speed things up. align 8 myebuf byte 16 dup(?) Title: Re: About LOCAL string Post by: NervGaz on September 16, 2009, 09:34:14 AM RtlZeroMemory should work fine... But IIRC it's a lot faster just using a "rep stosb/w/d" to do it...
mind you I haven't really been coding anything in asm for a good few years so I think someone else might be better suited to give and example that'll work straight away... I'll give it a shot tho... Code: xor eax,eax lea edi,szDir mov ecx,31 ;as it's a quarter of the buffers size rep stosd hopefully I got that right Title: Re: About LOCAL string Post by: ecube on September 16, 2009, 09:38:29 AM Quote from: NervGaz on September 16, 2009, 09:34:14 AM RtlZeroMemory should work fine... But IIRC it's a lot faster just using a "rep stosb/w/d" to do it... mind you I haven't really been coding anything in asm for a good few years so I think someone else might be better suited to give and example that'll work straight away... I'll give it a shot tho... Code: xor eax,eax hopefully I got that rightlea edi,szDir mov ecx,31 ;as it's a quarter of the buffers size rep stosd I disagree, back when I started the speed test thread on Zero memory functions http://www.masm32.com/board/index.php?topic=6576.0 , it was determined RtlZeroMemory was the fastest on buffers 1024 bit+ and masmlib memfill was faster on smaller buffers. I think RtlZeroMemory uses rep in its code anyway. Title: Re: About LOCAL string Post by: NervGaz on September 16, 2009, 09:43:42 AM Again it's been ages since I coded in asm, actually apart from a few filemaker scripts
(i know not even really coding) it's been ages since I coded anything... But yeah I remember a similar conversation about 7 or 6 years ago on a forum... Only reason i mentioned stosb/w/d was that the buffer in his example was 124 bytes long... Title: Re: About LOCAL string Post by: hutch-- on September 16, 2009, 09:56:33 AM A couple of things, in most instances when you allocate a buffer on the stack for text, you only ever need to write ONE ZERO at the start, not zero fill the entire buffer. As long as you don't try and write past the end of the allocated space, normal zero terminated string procedures only need to know the start address of the buffer.
If you really must zero fill the buffer, DON'T use REP STOSD as its slow on the first 500 bytes or so, do it in the normal manner using a DWORD sized register with zero in it. Title: Re: About LOCAL string Post by: NervGaz on September 16, 2009, 10:06:15 AM Goes to show how much I remember... heh...
Title: Re: About LOCAL string Post by: Slugsnack on September 16, 2009, 11:16:58 AM Quote from: E^cube on September 16, 2009, 09:38:29 AM Quote from: NervGaz on September 16, 2009, 09:34:14 AM RtlZeroMemory should work fine... But IIRC it's a lot faster just using a "rep stosb/w/d" to do it... mind you I haven't really been coding anything in asm for a good few years so I think someone else might be better suited to give and example that'll work straight away... I'll give it a shot tho... Code: xor eax,eax hopefully I got that rightlea edi,szDir mov ecx,31 ;as it's a quarter of the buffers size rep stosd I disagree, back when I started the speed test thread on Zero memory functions http://www.masm32.com/board/index.php?topic=6576.0 , it was determined RtlZeroMemory was the fastest on buffers 1024 bit+ and masmlib memfill was faster on smaller buffers. I think RtlZeroMemory uses rep in its code anyway. Source for RtlZeroMemory, taken from debugging in VC++ ( nice comments Microsoft ! ) : Code: memset proc \ dst:ptr byte, \ value:byte, \ count:dword OPTION PROLOGUE:NONE, EPILOGUE:NONE .FPO ( 0, 3, 0, 0, 0, 0 ) mov edx,[esp + 0ch] ; edx = "count" mov ecx,[esp + 4] ; ecx points to "dst" test edx,edx ; 0? jz short toend ; if so, nothing to do xor eax,eax mov al,[esp + 8] ; the byte "value" to be stored ; Special case large block zeroing using SSE2 support test al,al ; memset using zero initializer? jne dword_align cmp edx,0100h ; block size exceeds size threshold? jb dword_align cmp DWORD PTR __sse2_available,0 ; SSE2 supported? je dword_align jmp _VEC_memzero ; use fast zero SSE2 implementation ; no return ; Align address on dword boundary dword_align: push edi ; preserve edi mov edi,ecx ; edi = dest pointer cmp edx,4 ; if it's less then 4 bytes jb tail ; tail needs edi and edx to be initialized neg ecx and ecx,3 ; ecx = # bytes before dword boundary jz short dwords ; jump if address already aligned sub edx,ecx ; edx = adjusted count (for later) adjust_loop: mov [edi],al add edi,1 sub ecx,1 jnz adjust_loop dwords: ; set all 4 bytes of eax to [value] mov ecx,eax ; ecx=0/0/0/value shl eax,8 ; eax=0/0/value/0 add eax,ecx ; eax=0/0val/val mov ecx,eax ; ecx=0/0/val/val shl eax,10h ; eax=val/val/0/0 add eax,ecx ; eax = all 4 bytes = [value] ; Set dword-sized blocks mov ecx,edx ; move original count to ecx and edx,3 ; prepare in edx byte count (for tail loop) shr ecx,2 ; adjust ecx to be dword count jz tail ; jump if it was less then 4 bytes rep stosd main_loop_tail: test edx,edx ; if there is no tail bytes, jz finish ; we finish, and it's time to leave ; Set remaining bytes tail: mov [edi],al ; set remaining bytes add edi,1 sub edx,1 ; if there is some more bytes jnz tail ; continue to fill them ; Done finish: mov eax,[esp + 8] ; return dest pointer pop edi ; restore edi ret toend: mov eax,[esp + 4] ; return dest pointer ret memset endp end Title: Re: About LOCAL string Post by: ecube on September 16, 2009, 11:23:11 AM Nice Slugsnack :bg I wonder if lingo or the other speed guru's could speed that up. I'm suprised they used sse2, considering how a lot of other WinAPI are slow.
Title: Re: About LOCAL string Post by: Slugsnack on September 16, 2009, 11:51:44 AM Quote from: E^cube on September 16, 2009, 11:23:11 AM Nice Slugsnack :bg I wonder if lingo or the other speed guru's could speed that up. I'm suprised they used sse2, considering how a lot of other WinAPI are slow. Huhhh I don't see any SSE2 instructions lol. Only regular x86 ones Title: Re: About LOCAL string Post by: sinsi on September 16, 2009, 12:06:49 PM Well, you missed the interesting bit
Code: jmp _VEC_memzero ; use fast zero SSE2 implementation Title: Re: About LOCAL string Post by: ecube on September 16, 2009, 12:21:56 PM hehe woops :bg
Title: Re: About LOCAL string Post by: hutch-- on September 16, 2009, 01:53:52 PM Something that needs to be kept in mind with memory copy algos is if both locations, (source and destination) are already in processor cache. If they are the DWORD sized copy is reasonably fast but if the target and source are not in cache, you get cache pollution problems. REP MOVSD and the SSE/MMX version if written correctly read through cache but write back directly to memory which is usually faster when source and destination are not both in cache.
You test this by allocating two memory blocks that are large enough not to fit into cache then copy data from one to the other. Title: Re: About LOCAL string Post by: jj2007 on September 16, 2009, 08:49:25 PM For the lazy programmer - short and fast, works with all kind of LOCAL variables, including strings and structures:
Quote: MyTest proc LOCAL MyVar1:DWORD, LocBuffer[120]:BYTE, MyVar2:DWORD call ClearLocals ret MyTest endp Code: ClearLocals proc ; put "call ClearLocals" as first instruction after LOCALS - eax will be unchanged on exit push eax ; do not use with uses esi etc - push them manually behind the call! lea eax, [esp+8] ; pushed eax and ret address mov esp, ebp ; base page of calling procedure align 4 ; 74 instead of 123 cycles on Celeron M, no effect on P4 @@: push 0 ; 120 bytes: 196 cycles on P4 cmp esp, eax ; rep stosd?? ja @B sub esp, 8 ; 19 bytes with align 4 pop eax ret ClearLocals endp Title: Re: About LOCAL string Post by: NightWare on September 16, 2009, 09:34:28 PM Quote from: stbfish on September 16, 2009, 06:08:02 AM LOCAL szDir[124]:BYTE how to initialize it to all 0? like this szBuffer db 124 dup(0) when i define a LOCAL Var, what is the default value inside? to init/re-init a string you just need to clean the first byte, here : mov BYTE PTR szDir,0 coz there is NO REASONS to clean the entire area (at least if your string functions are well coded...). Title: Re: About LOCAL string Post by: ecube on September 16, 2009, 10:25:49 PM You guys like the caps...I tend to use buffers for alot more than strings, and that's why I recommended the full clearing, is a piece of mind for me and doesn't limit. If he's sure he's just gonna mess with strings then YEAH, clearing the first byte is sufficient.
The MASM Forum Archive 2004 to 2012 | Powered by SMF 1.0.12.
© 2001-2005, Lewis Media. All Rights Reserved. |