push OFFSET MyVar
call MyProc
or
lea eax,MyVar
push eax
call MyProc
I don't understand the difference! Thanks
Between "mov eax,OFFSET MyVar" and "lea eax,MyVar" there is no difference
in the result. Maybe the adressbuilding with a "lea" can be done a
little bit faster, if this command will be execute from an other unit
inside of the cpu.
For most of my subroutines i don´t push arguments on the stack.
Values, or adresses can be stored inside of unused register and if all
register are in use, so that i can´t store more arguments, then i use a
fixed ram location for to store arguments and at the beginning of the
subroutine i have to push all register that i want to use inside of the
subroutine on the stack before and pop it back before i return to the
caller. Between this i can load all arguments from the fixed ram location
into all pushed register and i can store any result nearby this ram
location too. So i don´t need to push/pop any argument on/from the stack.
Push/pop are some times slower on older cpus in relation with mov-commands
to a fixed ram adress.
Dirk
Well... you understand the distinction between a memory address and the
value stored at that address, right? "offset" is the keyword your
assembler uses to indicate the address, not the contents.
"lea" ("load effective address") is a funny instruction. It takes a
"contents of memory" reference as its second operand, but it doesn't
access that memory in any way. It merely calculates the address of that
memory, and loads it into the register specified in the first operand.
It is essentially an arithmetic instruction.
In this case, we're saying "tell me the address of the variable whose
address is MyVar". Kinda overkill. The "offset" form would give you
shorter code - they both do the same thing. "lea esi, [MyTable + ebx +
ecx * 8]" is the kind of thing "lea" will do!
However, suppose "MyVar" didn't *have* an "offset"? Suppose instead of
"MyVar dd 42", "MyVar" were a "local" (or "stack" or "automatic")
variable? We'd have code like (probably hidden by a "PROC" macro):
MyFunc:
push ebp
mov ebp, esp
sub esp, 4 ; make room on the stack for a local variable
MyVar textequ [ebp - 4] ; whatever the syntax is...
...
Now "push offset MyVar" isn't going to work! You'd *have* to use "lea"!
So you may want to use "lea" all the time - even though it's "overkill"
- so your code will still work if you change "MyVar" from a "static" to
a "local" variable.
Does that answer the question?
Best,
Frank
> or
at a first glance I'd say the second variant abuses eax ;)
But have you checked the difference by disassemble or debug ?
You'd see a value pushed in both variants which points to MyVar.
OFFSET is not a CPU instruction, your compiler takes the address
instead of the content of YourVar.
Other assemblers don't need OFFSET because they have a different
meaning of symbols by default:
push myvar ;pushes myvar's address
push[myvar] ;pushes the content of it
LEA eax,[myvar] ;is often just the same as MOV eax,myvar then
__
wolfgang
LEA is a CPU instruction, but as Wolfgang Kern points out, "OFFSET is
not a CPU instruction"
The practical implications of this difference involves the location of
the variable. For a variable defined statically at assembly time in
storage assigned to the program when it is loaded and activated, for
such a variable the two modes of acquiring its offset give the same
results. But for a variable defined dynamically in storage acquired by
the program during run time, only the LEA instruction can be used to
obtain its offset - the other alternative is not available.
Thanks Dirk , Frank , Wolfgang and Aharon.
Very good!
Now that others have given you a better understanding...
Some assemblers -- like MASM 5 and later -- will silently replace an
LEA with a MOV ... OFFSET if the target can be determined at compile
time.
This sort of optimization is controversial. (-:
--
Jim