News:

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

Main Menu

The lifetime of 'LOCAL' variable

Started by Jason, November 08, 2024, 03:23:15 PM

Previous topic - Next topic

Jason

Hi guys,

I was just reading about variables prefixed with the LOCAL keyword.

MSDN says these are stack based. So, at what point do they go out of scope? Do they have to be inside a proc to get removed from the stack and the memory they used freed up at that time?

Many thanks!

NoCforMe

#1
Yes. It's less complicated than a lot of explanations make it out to be. Not rocket surgery.

Since local variables are placed on the stack, they (obviously, if you think about it) go "out of scope" when the subroutine/function/whatever you want to call it exits, at which point those variables could be considered garbage anyhow since they can be overwritten at any time by any subsequent writes to the stack (PUSHes or subroutine calls).

The assembler makes it really simple: if you declare a LOCAL variable in a PROC, that variable is only accessible within that proc. You could have another LOCAL variable with the same name in a different subroutine, but that variable will be likewise only accessible within that routine. And you cannot access those variables from outside the PROC.

The memory isn't freed, because it was never really allocated: LOCAL variables are simply accessed as offsets from EBP (RBP in 64-bit) into the stack. So no malloc() or free() or any of that is needed. They basically just automagically vanish once the subroutine returns.

It's actually a really simple scheme that works very well. The same as used in C, C++ and other high-level languages.

Which brings to mind a classic rookie mistake: returning a pointer to a local variable in a subroutine.

Can you see what's wrong here and why it won't work? (It might work sometimes if you're lucky.)

xyz    PROC
      LOCAL someVar:DWORD

      MOV  someVar, SOME_VALUE
      ...
      ...

; Return a pointer to "someVar":
      LEA  EAX, someVar
      RET

xyz    ENDP
Assembly language programming should be fun. That's why I do it.

Jason


zedd151

Quote from: NoCforMe on November 08, 2024, 04:07:20 PM(Again, you could have another global variable outside of the function with the same name, but it would be a different variable.)
You cannot have a global variable with the same exact name as a local variable.  :biggrin:  Assembly Error:
test.asm(8) : error A2005: symbol redefinition : var1
include \masm32\include\masm32rt.inc

.data
    var1 dd 0
.code

start proc
local var1:dword

    invoke ExitProcess, 0
start endp

end start

You can have another local variable in a different procedure with the same exact name, though.

include \masm32\include\masm32rt.inc
differentproc proto                                           

.data
 ;    var1 dd 0
.code

start proc
local var1:dword

    invoke differentproc
    invoke ExitProcess, 0
start endp

differentproc proc
local var1:dword

    ret
differentproc endp

end start
Notice the global variable 'var1' is commented out... no assembly error.  :tongue:
:sad:

NoCforMe

Whoops, you're right. My bad.
Corrected. Thanks.
Wouldn't want to spread any misinformation here.
Assembly language programming should be fun. That's why I do it.

Jason

Quote from: NoCforMe on November 08, 2024, 05:32:31 PMWouldn't want to spread any misinformation here.

Word on the street, that's the death penalty around these parts.  :badgrin:

TimoVJL

weak symbols are difficult for linker.
compilers might mangle local symbols.
C++ was created partly for that reason.
May the source be with you

_japheth

Quote from: zedd151 on November 08, 2024, 04:51:59 PMYou cannot have a global variable with the same exact name as a local variable.  :biggrin:  Assembly Error:
test.asm(8) : error A2005: symbol redefinition : var1

Actually, you can. This code:

.386
    .model flat
    .code
p1 proc
local v1:dword
mov v1, 1
    ret
p1 endp

.data
v1 dd 0
.code
_start:
mov v1, 2

    end _start

is accepted by Masm. Just ensure that the global variable is defined after the local one.  :biggrin:

It's almost certainly just a Masm bug, though - however, when writing jwasm I took great care to copy such peculiarities.
Dummheit, gepaart mit Dreistigkeit - eine furchtbare Macht.

zedd151

Quote from: _japheth on November 08, 2024, 07:54:42 PMis accepted by Masm. Just ensure that the global variable is defined after the local one.  :biggrin:
Is that the kind of information that you want to present here in the Campus? To someone that may be learning assembly? (Not specifically only Jason, the OP, but also anyone else reading this thread,; guests, other new members, etc.)

While that may work, it is still error prone (for the user), as there is still a global variable and a local variable with the same exact name. = a variable naming conflict. (Or as ml puts it, a symbol redefinition)

A year from now, will they remember that there were two distinct variables with the same name?

Not exactly what I would call a best practice, but rather trickery.
:sad:

_japheth

Quote from: zedd151 on November 08, 2024, 11:52:42 PMIs that the kind of information that you want to present here in the Campus? To someone that may be learning assembly?

Yes ... I love to confuse newbies.  :tongue:

QuoteWhile that may work, it is still error prone (for the user), as there is still a global variable and a local variable with the same exact name.

It's actually how quite a few languages do handle this case: C, Pascal, ...

Perhaps not really a good programming practice, but tastes may differ ...
Dummheit, gepaart mit Dreistigkeit - eine furchtbare Macht.

zedd151

Quote from: _japheth on November 09, 2024, 01:17:10 AMIt's actually how quite a few languages do handle this case: C, Pascal, ...
Obviously this is nether a 'c' nor 'pascal' related forum, while we may have members here that use those languages, kind of beyond the scope here in this topic.  :greensml:
:sad:

Vortex

How to Access Global Variable if there is a Local Variable with Same Name in C/ C++?

QuoteWe can access a global variable if we have a local variable with same name in C using extern.

// C Program to demonstrate that we can access a global
// variable if we have a local variable with same name
#include <stdio.h>

// Global variable x
int x = 50;

int main()
{
// Local variable x
int x = 10;
{
extern int x;
printf("Value of global x is %d\n", x);
}
printf("Value of local x is %d\n", x);
return 0;
}

https://www.geeksforgeeks.org/how-to-access-global-variable-if-there-is-a-local-variable-with-same-name-in-c-cpp/

NoCforMe

Quote from: zedd151 on November 08, 2024, 11:52:42 PMIs that the kind of information that you want to present here in the Campus? To someone that may be learning assembly? (Not specifically only Jason, the OP, but also anyone else reading this thread,; guests, other new members, etc.)

Zedd, maybe take a chill pill? I'm sure even the n00bs can digest this pretty easily. After all, it's just an aside to the main issue (the scope of LOCALs), and maybe it's not such a bad thing if they learn--horror of horrors!--that yes, MASM has bugs and quirks.
Assembly language programming should be fun. That's why I do it.