I didn't see this macro anywhere - may I missed it :P -
So there is it.
; -----------------------
;; ZEROLOCALS [n] - n stays for how many GPR was pushed in "uses"
; -----------------------
ZEROLOCALS MACRO N
LOCAL X
IFNB <N>
X = @SubStr(<N>,1)*4
ELSE
X = 12
ENDIF
xchg edx, edi
mov edi, esp ; transfer esp to EDI
add edi, X ; add n*4, skips the pushed esi or edi or ebx
mov ecx, ebp
sub ecx, edi
sar ecx, 2
xor eax, eax
rep stosd
xchg edx, edi
ENDM
sample:
.686p
.model flat
include ..\Macros.inc
.code
MySUB proc near stdcall uses esi edi ebx Param01:DWORD
LOCAL Buffer[12] :BYTE
ZEROLOCALS
;Your code
ret 4
MySUB endp
end
See this thread (http://www.masm32.com/board/index.php?topic=12306.msg94399#msg94399).
Ops.. :red
I gues we need a subsection for MACROs for easier look up. ::)
this is something you usually see in a basic compiler, the spec of local values being either zero or a null string.
I fail to see what is wrong with doing it manually.
mov local1, 0
mov local2, 0 etc ....
OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE
SomeDamnProc proc someParm1:dword,someParm2:dword
local1 TEXTEQU [ebp-4]
local2 TEXTEQU [ebp-8]
local3 TEXTEQU [ebp-12]
push esi
push edi
push ebx
push ebp
xor eax,eax
mov ebp,esp
push eax ;zero local1
push eax ;zero local2
push eax ;zero local3
:8)
Quote
I fail to see what is wrong with doing it manually.
Nothing.
But imagine you have a proc with 3-4 (or more) localy declared windows structures.
Lots of times you use only 1-2 members from maybe 10 but the rest have to be zero before calling the api.
Or you have buffers which you have to empty time to time.
Or .... :bg
puffers ? :eek
ohhhhhhhhhhh - buffers ! - lol
I'm shore he meant tuffers... we all know what tuffers are :lol :lol
On the rare occasion that you must zero large amouns of local addressing, just use a memfill routine, saves messing around with the stack in almost all instances.
Generally speaking, if im using locals in a routine, i will do as Hutch suggested, inline. Point EDI at the start of your buffer, zero al, set ECX to size of buffer and then rep stosb. Larger buffers i will use rep stosd. I dont have any need to for a rep stosb to catch any trailing bytes, the locals are always on a DWORD alignment.
Its no hassle and if im worried about saving registers, i'll simply incorporate the uses directive. I know i can manually push the registers but its a feature of MASM so i'll use it :D. Most things i write arent that time critical that the zeroing of the buffers will cause a bottleneck and for anything which needs speed, i zero only as i absolutely need to.
HR,
Ghandi
Quote
ohhhhhhhhhhh - buffers ! - lol
Quote
I'm shore he meant tuffers...
He.. He.. He. :bdg
I like to see that you guys hungarian is match up with my english. :toothy
Quote
Generally speaking, if im using locals in a routine, i will do as Hutch suggested, inline. Point EDI at the start ....
That's exactly the macro is doing above. :P
Yes, but its a macro, where i was saying i have no problems with typing a few extra lines manually. I was merely joining in the thread. As the other thread linked points out, RtlZeroMemory seems to be an efficient API (o0 can this be right? hehe, j/k) but its just a personal preference of mine that i code most things manually. What another person does is no concern of mine and its a case of 'horses for courses', there was no criticism from me.
If i did want to macro it, i'd probably just do something slow and which requires some (very) basic math to provide the correct dword count:
ZeroLocals MACRO dwNumDwords
push edi
xor eax,eax
lea edi,dword ptr [esp+4]
mov ecx,dwNumDwords
rep stosd
pop edi
EndM
Once again, no time critical stuff with this... Its slow (uses rep stosd) but it works, there is also no support for the 'uses' directive. Like i said, i like to manually code things, so macros arent my forte' either.
HR,
Ghandi
Quote
no time critical stuff with this... Its slow (uses rep stosd)
That's a myth. :bg
"rep stosd" is just as fast as RtlZeroMemory. :P
Funny enough, unoless you are zeroing over 500 bytes, REP STOSD is not a good choice, its known to be slow in this context. If you must zero locals on entry and you don't want to run the zero instructions inline, a DWORD loop will do it with less registers and faster if its under 500 odd bytes.
push is pretty fast....
mov ecx,LocalsQty
xor eax,eax
ZeroLs: dec ecx
push eax
jnz ZeroLs
and only 11 bytes i think :8)
Quote from: Ficko on December 15, 2009, 12:37:48 PM
I gues we need a subsection for MACROs for easier look up. ::)
Hutch I really mean it.
There are 1000 of usefull - or not :P - macros scattered all over the forum and since MASM is a (MACRO)ASM I think it would deserve a MACROs section.
You have, its called the Laboratory. :bg
Quote from: hutch-- on December 15, 2009, 03:37:40 PM
You have, its called the Laboratory. :bg
Very funy. :green2
Why won't admit you just hate macros!? :toothy
QuoteYou have, its called the Laboratory.
lol - you hafta get up pretty early to make Hutch do a bunch of un-scheduled stuff :lol
it has little to do with his like/dislike of macros
you know what they say, "Want in one hand, ...... See which one fills up faster."
Quote from: Ficko on December 15, 2009, 04:25:46 PM
Quote from: hutch-- on December 15, 2009, 03:37:40 PM
You have, its called the Laboratory. :bg
Why won't admit you just hate macros!? :toothy
You are barking at the wrong tree. Hutch has provided an awful lot of very good macros, see \masm32\mtacros\macros.asm
Re Zerolocales ot ClearLocals or whatever, that has been bashed to death already. My link points to a 19 byte proc that requires a 5 byte call and no hand-made counting how many bytes need to be cleared. It's a matter of taste...
Quote from: jj2007 on December 15, 2009, 05:29:36 PM
?#!?*%&§...
Did I stept on your precious toes jj ?
I was just teasing him. :wink
Quote from: Ficko on December 15, 2009, 07:00:33 PM
Quote from: jj2007 on December 15, 2009, 05:29:36 PM
?#!?*%&§...
Did I stept on your precious toes jj ?
I was just teasing him. :wink
Oops, I thought you were serious - apologies ::)