News:

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

Lea, Offset, and Addr

Started by Bieb, January 11, 2005, 05:04:11 PM

Previous topic - Next topic

Bieb

Just wondering

  • Is there any difference between using LEA and mov dest, Offset src?
  • Is there any difference between (for parameters to a function) using LEA and using Addr?

Do these statements end up resolving to Lea instructions, or does MASM handle them in a different way?

Tedd

Short answer: Yes. (they're different)

Long answer:

LEA and MOV are entirely different instructions.
For most cases "MOV dest,OFFSET label" is okay, but this only works for places where you can get a constant address (data in the .data/.data? sections.) LEA is useful finding addresses of LOCAL variables, through ebp and an offset (LEA eax,[ebp-8]) where you just type "LEA eax,[myvar]"
When you use ADDR in invoke, if will usually just push the address if it can, if not then it will do "LEA eax,[whatever]" and "PUSH eax"
Hope that clears it up ;)
No snowflake in an avalanche feels responsible.

MichaelW

http://www.masmforum.com/simple/index.php?topic=247.0

To clarify, a "constant" address is one that is known at compile time. The address of stack (LOCAL) variables and procedure parameters are not known at compile time, so the address must be calculated at run time using LEA.
eschew obfuscation

JPlayer

Now i'm not sure why you would want to do it this way, but can you? Instead of doing
lea eax, [ebp-8]
could you instead do
mov eax, ebp
sub eax, 8

cause all that lea is doing is computing ebp-8 and then putting it in eax, right? Do you even need to calculate the address? could you do stuff like:
mov eax, [ebp-8]
to put the value stored at [ebp-8] into eax and
mov [ebp-8], eax
to put the value of eax into the location [ebp-8]?

tenkey

Yes, you can avoid using LEA, if you want to use the SUB instruction. Or load or store directly to the LOCAL variable.

There are API that require addresses of variables, and if they are LOCAL, you (or INVOKE) must use either LEA or do the math.
A programming language is low level when its programs require attention to the irrelevant.
Alan Perlis, Epigram #8

rea

I only whant to introduce a little noise ;).

But I think that the assembler cant know the final address of a relocatable executable???

The assembler can know the address related to the start of the section depending in how many instructions (bytes) are before for calculate this one, when the loader loads your program is where finally the address is know.

Also the assembler calculations can be modificated directly indicating that you whant to take a new start for count the news instructions after such line.

Only is posible that the assembler know at  assembly time the real address if the executable is not relocatable I guess.


Imagine this related to the addresses specificated when you directionate then via any register that can be used for this, isnt easy for the assembler/compiler calculate such things ;)...

Tedd

Quote from: JPlayer on January 13, 2005, 01:35:45 AM
lea eax, [ebp-8]
could you instead do
mov eax, ebp
sub eax, 8

Yes, you 'can' do that. And yes, you can also "mov eax,[ebp-8]" etc.
But you can't do "mov eax,OFFSET [ebp-8]" which is what you use lea for ;)
The point of it is when you need the address of the variable, rather than the actual value, which is useful (as TenKey said) for functions that require this.


rea
You're right, the assembler doesn't know where your program will be loaded to, but it assumes a value and sticks to that. This address is written in the PE format, so when the loader gets to it, it just loads it at that address and everything is okay. Unless that address isn't avaible, in which case the image needs to be relocated - which is also okay as long as the image has .reloc section which tells what bytes need changing. In relation to this thread, yes you could do away with all fixed addresses and access everything by base+offset, but this is usually slower and uses up a whole register (we don't have many anyway!)
No snowflake in an avalanche feels responsible.

MichaelW

rea,

A "real" address for code labels is not needed. The assembler uses the addresses related to the start of the section to calculate a relative address (a "displacement") and encodes that into your jumps and calls. These relative addresses work the same for any load address. At run time the destination address is calculated by adding the encoded displacement to the address of the next instruction.

    jmp   @F
    nop
    nop
  @@:
    call  procx
    nop
    nop
    nop
procx proc
    ret
procx endp

00401000 EB02            jmp     loc_00401004 ;displacement=02
00401002 90              nop                  ;401002+2=401004
00401003 90              nop
00401004             loc_00401004:
00401004 E803000000      call    fn_0040100C  ;displacement=00000003
00401009 90              nop                  ;401009+3=40100C
0040100A 90              nop
0040100B 90              nop
0040100C             fn_0040100C:
0040100C C3              ret

eschew obfuscation