News:

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

Local variables not on the stack

Started by bf2, July 28, 2011, 04:52:54 PM

Previous topic - Next topic

bf2

Local variables - but not on the stack

I am sure I have got everything mixed up - but I read that local variables are created on the stack, yet I can create 'local' variables which are not on the stack.

My procedure looks like this:

INCLUDE \masm32\include\masm32rt.inc
.DATA
localVar DD ?
.CODE
MyProc PROC
MOV localVar, 32
RET
MyProc ENDP
END


The symbol localVar is not visible to the caller, so it is 'local' to the procedure. Yet in the debugger, I don't see 20 being moved to a location in the stack. I do see 20 being moved to a memory location.

I am confused!

Thanks.

dedndave

 :bg
naming a variable "local" does not make it so
the label name is just a text string that the assembler recognizes as unique
the name, itself, has little to do with the variable type or scope
in your example, "localVar" is a global declaration
it is available to any procedure that may reference it

as for debug....
you have not specified a program entry point
QuoteThe symbol localVar is not visible to the caller
i don't see any caller - lol

try this...
        INCLUDE \masm32\include\masm32rt.inc

;-----------------------------------------------

        .DATA?

localVar dd ?

;-----------------------------------------------

        .CODE

_main   PROC

        call    MyProc
        INVOKE  ExitProcess,0

_main   ENDP

;-----------------------------------------------

MyProc  PROC

        mov     localVar,32
        ret

MyProc  ENDP

;-----------------------------------------------

        END     _main


you will see that it is actually a global variable

Neil

Declare your variable within your proc :-

LOCAL localVar   :DWORD

Now it will be on the stack  :U

mineiro


INCLUDE \masm32\include\masm32rt.inc

.DATA ;global initialized data here
my_global_initializated DD 1234

.data? ;global unitializated data here
my_global_unitializated dd ?

.CODE

MyProc PROC  ;inside this procedure we have local unitializated var
LOCAL my_local_var:DWORD
mov my_global_unitializated,31
MOV my_local_var, 32
RET
MyProc ENDP

END MyProc

bf2

I think I didn't explain myself properly. I wasn't suggesting that calling a variable localVar makes it local. No, even I am not that dumb  :lol.

I was saying that
a) if a symbol is defined in a procedure and not in the caller, then the caller cannot access the symbol. You get an 'undefined symbol' assembly error. That suggests to me the symbol is 'local' to the procedure.
b) Even though this symbol is 'local' to the procedure, it is does not exist on the stack, it exists on the global memory where the main thread runs - that's what I am confused about.

I am not talking about the LOCAL directive. Let's assume the directive does not exist. I know the procedure can create unnamed variables in the stack and then remove them, so they are truly local variables, I know these things. But my question is what is my localVar in the current situation?

Thanks.

dedndave


dedndave

here is a better example of a global variable
basically speaking, if it is in .DATA, .DATA?, or .CONST sections, it is globally available
that does not apply to data declared in different modules
in order for data defined in a particular object module to be visible to other modules, it has to be made public
you can do this with PUBLIC or with EXTERNDEF
the same is not true of procedures, they are PUBLIC by default, and may be made PRIVATE

however, for data within the same module...
        INCLUDE \masm32\include\masm32rt.inc

;-----------------------------------------------

        .DATA?

GlobalVar dd ?

;-----------------------------------------------

        .CODE

_main   PROC

        call    MyProc
        mov     eax,GlobalVar
        print   ustr$(eax),13,10
        INVOKE  ExitProcess,0

_main   ENDP

;-----------------------------------------------

MyProc  PROC

        mov     GlobalVar,32
        ret

MyProc  ENDP

;-----------------------------------------------

        END     _main


code labels within the same module are local (private) if inside a PROC
otherwise, they are global
you can make a code label inside a PROC global by using 2 colons instead of 1
SomeProc PROC

SomeLabel::

SomeProc ENDP

        jmp     SomeLabel

Vortex

Here is another approach :


include     LocalVars.inc

var1        equ <DWORD PTR [esp+4]>
var2        equ <DWORD PTR [esp]>

.data

f1          db 'var1 + var2 = %d',0

.code

start:

    add     esp,-2*4    ; reserve 8 bytes
                        ; for two variables

    mov     var1,10
    mov     var2,20

    mov     eax,var1
    add     eax,var2

    invoke  crt_printf,ADDR f1,eax

    add     esp,2*4     ; release the variables

    invoke  ExitProcess,0

END start



bf2

OK, I think I am beginning to get this.

But...

In my example, assuming my procedure is in a separate module, we have a variable that is
- defined in the procedure
- not visible from another procedure in a separate module
- exists in the global memory.

What should we call such a variable - local variable or global variable? Clearly not local, because it's not defined on the stack. Clearly not global because it's not visible from a different module.

Apologies for being obtuse, but I am really trying to understand.

dedndave

it is global/private

Quote- defined in the procedure

it does not matter - if it is in .DATA, .DATA?, or .CONST, it is global
generally speaking - if it is defined in any section, it is global

clive

Quote from: bf2
In my example, assuming my procedure is in a separate module, we have a variable that is
- defined in the procedure
- not visible from another procedure in a separate module
- exists in the global memory.

But you're NOT defining it in the procedure, you are assigning a variable defined in the DATA segment with a value.

It will not be visible to other modules unless you make it PUBLIC.

It will never the less contaminate the name space of your entire module, while defining it locally within your procedure would not.

Only LOCAL variables are allocated on the stack. You can also manage the stack manually/explicitly.

Quote
What should we call such a variable - local variable or global variable? Clearly not local, because it's not defined on the stack. Clearly not global because it's not visible from a different module.

Perhaps a static variable.

In C

static int foo;

int bar(void)
{
  return(foo++);
}
It could be a random act of randomness. Those happen a lot as well.

MichaelW

To make a variable, label, or symbol defined in one module visible in another module you can use the EXTERNDEF directive.
eschew obfuscation

jj2007

You may have

- public global variables, in the .data or .data? section, visible to all modules (but most proggies fit in one module, so this is rarely relevant)
- private global variables, in the .data or .data? section, visible only in the current module (the normal case)
Note global variables in the .data? section are initialised to zero. Thus there is no need to have a MyVar dd 0 in the .data section (.data bloats the *.exe, .data? doesn't)
- local variables, defined at the beginning of a proc

The latter reside on the stack, and will contain garbage on entry into the proc, which means you need to explicitly initialise them if you need any specific value (I note this because most high level languages initialise them to zero - Masm doesn't !).

Under the hood, LOCAL is just a macro that gives a name such as MyLocalDword to an offset to ebp. More here.

clive

       .386
       .MODEL  FLAT,C
       .DATA
       PUBLIC  localVar
localVar DD ?
       .CODE
MyProc PROC
       MOV localVar, 32
       RET
MyProc ENDP
       END MyProc
It could be a random act of randomness. Those happen a lot as well.

clive

Quote from: jj2007I note this because most high level languages initialize them to zero - Masm doesn't !

C doesn't initialize them either, one should always assume stack space allocations will contain undefined content, unless the language definition explicitly states otherwise.
It could be a random act of randomness. Those happen a lot as well.