Comments ??
What is so dangerous about uninitialized variables ?
Do some operating systems set it to zero in case the programmer "boofed up" ?
Any decent one should. Otherwise, a pgm could steal other pgms
or OS data. Just ask for memory, scan it, release, repeat.
So OSes have a bzero() routine to rapidly clear pages when one is
needed (most often for writing). Memory management on a modern
OS is a complex subject, greatly assisted by x86 hardware VM.
Zero is a very good fill because it enables trapping null pointer
errors at runtime. The zero page (addresses 00000000h-00001000h)
is never allocated, and any reference to it reading or writing
generates a hardware error that OS software can manage.
-- Robert
Well, Windows has a dedicated thread for zeroing unused pages.
I'm pretty sure that memory allocated is guaranteed to be zero filled.
That's one good thing about the .data? section, everything is initialised to zero.
yes - it seems it is
when i first started writing win32 code, i was clearing it out myself
an old habit from 16-bit days - lol
DOS would hand you the memory filled with whatever was there before (usually garbage)
Windows sets it to 0, if it isn't already 0'ed by the idle thread
Jochen had to convince me of that :biggrin:
I always have Initialisation routines that zero everything.. and always init variables to a known state prior to re/use.
8)
It seems that locals are not initialized but contain "garbage" by default?
How could one determine the size of the locals to initialize them? ebp - addr (of last local) ?
main PROC
LOCAL dwNumber :DWORD
LOCAL fmtNum[32] :BYTE
LOCAL pfmtNum :DWORD
LOCAL dwLastErr :DWORD
LOCAL szError[1024] :BYTE
invoke crt_printf,chr$("dwNumber...: 0x%xh %u",13,10),dwNumber,dwNumber
invoke crt_printf,chr$("dwLastErr..: 0x%xh %u",13,10),dwLastErr,dwLastErr
; output:
; dwNumber...: 0xfffffffeh 4294967294
; dwLastErr..: 0xe307e8f0h 3808946416
Didn't post here for a long time, so this "Verification"-thing surprised and amused me.
f.ex. do real programmers know what country Ghandi came from? :biggrin:
how can you know which way the rain falls, if you sit in front of your box all of the time? :eusa_dance:
I'd suggest questions like:
Is Bill Gates a capitalist, communist or fasist? :t
How many bytes does a DWORD have, 1, 4, 32 or 256? :lol:
and so on.
there's probably a masm pseudo-op for that
but, i can see by addition that you have 1070 bytes of locals
the lowest address is [ebp-1070] and the highest is [ebp-1]
[ebp] is where the preserved value of ebp is
storing locals for the main proc is a little bit silly, though - lol
you could just put them in the uninitialized data section and they'll be initialized to 0 for you
Sounds like a storm in a teacup, if you want either initialised OR uninitialised memory, just do it. :biggrin:
Hi cobold,
The uninitialized local variables in the stack contains random data.
I get 1068 bytes of locals, [ebp-4] to [ebp-1068].
include \masm32\include\masm32rt.inc
.code
main proc
LOCAL dwNumber :DWORD
LOCAL fmtNum[32] :BYTE
LOCAL pfmtNum :DWORD
LOCAL dwLastErr :DWORD
LOCAL szError[1024] :BYTE
lea eax, dwNumber
sub eax, ebp
printf("dwNumber [ebp%d]\n",eax)
lea eax, fmtNum
sub eax, ebp
printf("fmtNum [ebp%d]\n",eax)
lea eax, pfmtNum
sub eax, ebp
printf("pfmtNum [ebp%d]\n",eax)
lea eax, dwLastErr
sub eax, ebp
printf("dwLastErr [ebp%d]\n",eax)
lea eax, szError
sub eax, ebp
printf("szError [ebp%d]\n\n",eax)
inkey
ret
main endp
end main
The first question of this thread was: So what's wrong with uninitialized variables? It depends. Sometimes the algorithm requires factory default values, sometimes the value can only be calculated during run time etc. Local variables reside on the stack and contain by nature garbage before initialization. Erol is right.
Gunther
oops - you got me, Michael - lol
at any rate....
my point was that the main procedure has a lifespan, pretty much the same as the process
no need to use locals in that case
memory is memory - so, your not saving anything
in this case, he also wants them zero'ed out - why not use uninitialized data
it also frees up EBP to use as a preserved general register in the scope of main
Quote from: dedndave on January 01, 2014, 03:14:20 AM
oops - you got me, Michael - lol
at any rate....
my point was that the main procedure has a lifespan, pretty much the same as the process
no need to use locals in that case
memory is memory - so, your not saving anything
in this case, he also wants them zero'ed out - why not use uninitialized data
it also frees up EBP to use as a preserved general register in the scope of main
Dave,
If you want recursive functions, you cannot easily use uninitialized memory, you need the stack. I say "easily use" because you can use the Variable as a pointer to a block of storage, and increment the pointer(s) for each recursion, and then use CALLs without parameters or local storage, saving the stack to only hold the return location.
This then leaves EBP free to use as an extra general register.
Dave.
right
but, look at the original post :biggrin:
we are talking about the main PROC
it's not usually recursive or reentrant
main PROC
LOCAL dwNumber :DWORD
LOCAL fmtNum[32] :BYTE
LOCAL pfmtNum :DWORD
LOCAL dwLastErr :DWORD
LOCAL szError[1024] :BYTE
Dave,
You are right about the OP, but the use of uninitialized storage can also be used for other function calls without parameters to make EBP available as a general register.
Dave.