News:

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

Confused about global, and local scope data

Started by gwapo, January 11, 2006, 05:33:11 AM

Previous topic - Next topic

gwapo

Hi I'm new here, but I'm not new in assembly programming :wink

I got a question and where I admit got confused in this,

My question is about the scope of my data, if I do this:


.data?
wcx WNDCLASSEX <>


What's the difference of doing it this way?


local wcx:WNDCLASSEX


I would appreciate it if somebody expain this to me, about the difference between global, public, private and local?

Also, how would I enforce local scope in MASM without declaring as local varname:type? (I mean, what's the advicable way of setting the scopes?)


Thanks in advance,

-chris

MichaelW

Hello chris, welcome to the forum.

The first method allocates space for the structure in the uninitialized data segment. The data has global scope You cannot specify initializers because the data is not stored in the EXE (AFAIK space for the data is allocated by the loader).

The second method allocates space for the structure from the stack, at run time, when the procedure is called. The data has local scope. The LOCAL directive will not allow you to specify initializers.

You can make a variable in the .data or .data? segment effectively local by allocating the data from within a procedure.

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    include \masm32\include\masm32rt.inc
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    .data
      globaldd1 dd 0
    .data?   
      globaldd2 dd ?
    .code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    print ustr$(globaldd1),13,10
    print ustr$(globaldd2),13,10
    ;print ustr$(localdd1),13,10 ; error A2006: undefined symbol
    ;print ustr$(localdd2),13,10 ; error A2006: undefined symbol
    call aproc
    inkey "Press any key to exit..."
    exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
aproc proc
    .data
        localdd1 dd 0
    .data?
        localdd2 dd ?
    .code   
    print ustr$(globaldd1),13,10
    print ustr$(globaldd2),13,10
    print ustr$(localdd1),13,10
    print ustr$(localdd2),13,10
    ret
aproc endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start


eschew obfuscation

gwapo

Hi Michael,

Thanks for your response, your code really clears a lot  :U

I understand that we can set local scope, but what I really want to know is, how does local really work? Does it allocate data somewhere in memory where it actually inaccessible outside the proc or does it doing something else like allocating heap?

We know that proc is just an address in the code where we can branch, something like this:


procname:

pop param1
pop param2

; code here

add esp, 8
ret


I was just thinking, how does local mark the data as local? does it doing it like this?


procname:

pop param1
pop param2

jmp skipdata

localdd1 db "My local data", 0

skipdata:

; code here

add esp, 8
ret


We know that localdd1 is accessible outside the proc that way, but probably I'm thinking it in the wrong way, or I was just thinking too much  :green

PS. Pardon my ignorance, but what's print ustr$ commmand and where can I get this?

Thanks again mike,

-chris

Mirno

Michael, using .data within a proc does not scope it locally to that procedure (it'd be good if it did but it doesn't).
The reason it "worked" in your example is because of MASMs inability to forward reference. If you copy and paste the proc between the ".code" and the "start:" lines, then it'll allow the two lines you had to comment out (instead you'll need to define a "PROTO" for the function).

MASM does not support the idea of namespaces, which is really what C does when a variable is declared static (it's placed with the global data, but the name for access is scoped in a similar way to that of namespaces).

gwapo, the way the functions work is:

push var2      ; <var2>
push var1      ; <var1> <var2>
call proc      ; <return addr> <var1> <var2>
...


proc:
push ebp       ; <old ebp> <return addr> <var1> <var2>
mov  ebp, esp
add  esp, 20h  ; <locals> <old ebp> <return addr> <var1> <var2>
;                             ^
; ebp points here             |
; So to access parameters, we use ebp - (some number) for locals
; and                             ebp + (some number) for parameters


Luckily, keeping track of where things are is all handled for us by MASM, but ebp + 8 is the first parameter, + 12 is the second etc.

Mirno

k3Eahn

Mirno,
You forgot a minus in front of 20h  :wink
Quote
push var2      ; <var2>
push var1      ; <var1> <var2>
call proc      ; <return addr> <var1> <var2>
...


proc:
push ebp       ; <old ebp> <return addr> <var1> <var2>
mov  ebp, esp
add  esp, 20h  ; <locals> <old ebp> <return addr> <var1> <var2>
;                             ^
; ebp points here             |
; So to access parameters, we use ebp - (some number) for locals
; and                             ebp + (some number) for parameters

MichaelW

Quote from: Mirno on January 11, 2006, 02:30:10 PM
Michael, using .data within a proc does not scope it locally to that procedure (it'd be good if it did but it doesn't).
The reason it "worked" in your example is because of MASMs inability to forward reference.

Yes, thanks. Too little sleep and/or not enough caffeine.

eschew obfuscation

gwapo

Quotegwapo, the way the functions work is: ...

Thanks a lot Mirno, now it's crystal clear to me  :U

Just a follow-up question regarding ebp - <locals> -- does MASM perform "local data" destruction automatically as soon as we exit the procedure?


-chris

hutch--

Effectively yes, a masm stack frame has,


leave
ret [bytecount]


The "LEAVE" mnemonic restores ESP and the RET [BYTECOUNT] balances the stack.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php