News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

uninitialized variables

Started by Magnum, December 07, 2013, 03:26:34 PM

Previous topic - Next topic

Magnum

 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
Take care,
                   Andy

Ubuntu-mate-18.04-desktop-amd64

http://www.goodnewsnetwork.org

sinsi

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.

dedndave

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:

K_F

I always have Initialisation routines that zero everything.. and always init variables to a known state prior to re/use.
8)

'Sire, Sire!... the peasants are Revolting !!!'
'Yes, they are.. aren't they....'

cobold

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   


cobold

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.

dedndave

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

hutch--

Sounds like a storm in a teacup, if you want either initialised OR uninitialised memory, just do it.  :biggrin:

Vortex

Hi cobold,

The uninitialized local variables in the stack contains random data.

MichaelW

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


Well Microsoft, here's another nice mess you've gotten us into.

Gunther

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
You have to know the facts before you can distort them.

dedndave

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

KeepingRealBusy

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.

dedndave

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

KeepingRealBusy

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.