Page 1 of 2

Another dumb-ass FASM question!

Posted: Thu Mar 01, 2007 10:27 pm
by srod
Hi,

can anyone tell me what the difference is between the statement:

Code: Select all

MOV EAX, MyLabel
and

Code: Select all

LEA EAX, MyLabel
and

Code: Select all

LEA EAX, [MyLabel]
A few tests with a register dump program suggest that they all produce the same results! If this is so then I'm wondering as to the purpose of the LEA command?

Thanks.

Posted: Thu Mar 01, 2007 10:54 pm
by KarLKoX
From my asm help :
LEA - Load Effective Address
Usage: LEA dest,src
Modifies flags: None
Transfers offset address of "src" to the destination register.
Clocks Size
Operands 808x 286 386 486 Bytes
reg,mem 2+EA 3 2 1 2-4
- the MOV instruction can often save clock cycles when used in
place of LEA on 8088 processors


8D / r LEA r16,m Store effective address for m in register r16
8D / r LEA r32,m Store effective address for m in register r32

Posted: Thu Mar 01, 2007 10:58 pm
by srod
Ah, must have missed that in the various texts I use. :)

I was just wondering if I was doing something wrong in not using LEA at all!

Thanks.

Posted: Thu Mar 01, 2007 11:30 pm
by Demivec
- lea versus mov :

Code: Select all

lea edx,[edi]  ;load the contents of the edi into the edx (1)
mov edx,[edi]  ;load the value at edi into the edx        (2)
mov edx,edi    ;move the contents of the edi into the edx (3)
- (1) and (3) are equivalent.

- So what are the differences?

- (3) is faster than (1) and is preferred.
- However, mov only works with single args and cannot be used with LIST [ edi ].
- lea can take any address, e.g., lea esi , [ ebx + edi ]
Just a little something to throw into the mix. You would use LEA to handle a larger range of addresses, when a smaller range (within MOV limitations) is actually used the Assembler would substitute a MOV instruction instead (for speed).

*EDIT: LIST (in the example above) is any constant. The translation is that with MOV you can't compute an address by including it in the instructions arguments because it only takes one argument. LEA allows multiple arguments and it will compute the address from them.

Posted: Fri Mar 02, 2007 12:04 am
by srod
Thanks.

Mind if I ask what LIST[EDI] does? I can't recall seeing this.

:)

Posted: Fri Mar 02, 2007 12:22 pm
by Derek
srod wrote:Ah, must have missed that in the various texts I use. :)

I was just wondering if I was doing something wrong in not using LEA at all!

Thanks.
Have you got the asm.help files in your pb help directory?

That's where the quote from KarLKoX came from.

Very handy as you can just press F1 to bring up help in the normal way.

Posted: Fri Mar 02, 2007 2:01 pm
by srod
But I'm not creating in-line assembly as such, I'm actually creating some MS COFF format object files and so am not working within the PB IDE.

I have various asm help files, including the one you mention, but just missed the aforementioned reference.

Posted: Fri Mar 02, 2007 2:28 pm
by Derek
Ok.

Posted: Sun Jun 03, 2007 11:20 am
by gebe
Demivec wrote:
- lea versus mov :

Code: Select all

lea edx,[edi]  ;load the contents of the edi into the edx (1)
mov edx,[edi]  ;load the value at edi into the edx        (2)
mov edx,edi    ;move the contents of the edi into the edx (3)
- (1) and (3) are equivalent.

- So what are the differences?

- (3) is faster than (1) and is preferred.
- However, mov only works with single args and cannot be used with LIST [ edi ].
- lea can take any address, e.g., lea esi , [ ebx + edi ]
Just a little something to throw into the mix. You would use LEA to handle a larger range of addresses, when a smaller range (within MOV limitations) is actually used the Assembler would substitute a MOV instruction instead (for speed).


To really find the difference :
Try

Code: Select all

lea edx,[edi+4]  ;load the contents of the edi with  4  added to it into edx    (1)
mov edx,[edi]  ;load the value at edi into the edx        (2)
mov edx,edi    ;move the contents of the edi into the edx (3)
; if you try mov edx,edi+4 NO GO !!

;but (1) result edx = edi +4 (load effective address)L E A
;(3) result edx=edi cannot do :mov edx.edi+4

Am I correct ???

gebe :?:

Posted: Sun Jun 03, 2007 12:23 pm
by Trond
Lea is good because if you have a mov instruction (which will move data) you can always simply substitute the mov and leave the operands as they are and you will get the address of that data.

Since you can use mov to get the address of something as well their functionality overlaps a bit.

Posted: Sun Jun 03, 2007 12:55 pm
by gebe
Trond,
Yes ,except that you cannot do: mov eax,edi+4
The compiler objects to that.
Enjoy the rest of your Week-end.

gebe

Posted: Sun Jun 03, 2007 1:46 pm
by Trond
gebe wrote:Trond,
Yes ,except that you cannot do: mov eax,edi+4
The compiler objects to that.
Enjoy the rest of your Week-end.

gebe
You can't do lea eax, edi+4 either. But you can do lea eax, [edi+4] and mov eax, [edi+4].

Posted: Sun Jun 03, 2007 2:08 pm
by gebe
Trond wrote:
gebe wrote:Trond,
Yes ,except that you cannot do: mov eax,edi+4
The compiler objects to that.
Enjoy the rest of your Week-end.

gebe
You can't do lea eax, edi+4 either. But you can do lea eax, [edi+4] and mov eax, [edi+4].
The compiler accepts it but

The result will be different !
lea eax,[edi+4] will put in eax what is in edi to which value 4 is added

mov eax,[edi+4] will put in eax what is at the address pointed to by edi+4

(I think),lets check it out and recontact here.

gebe

Posted: Sun Jun 03, 2007 3:33 pm
by gebe
Trond,

The tests

Code: Select all

;enable inline asm
;put a break point everywhere
;and show the ASM debug window
v1.l=256+255;0x1ff
v2.l=256*2+255;0x2ff
v3.l=256*3+255
Debug Hex(v1)+ "   " +Hex(v2) + "  "+Hex(v3)
 
*v1=@v1
*v2=@v2;hopefully they'll be following each other
*v3=@v3
Debug "Address  v1 (*v1) :  " +Hex(*v1)
 Debug "Address  v2 (*v2) :  " +Hex(*v2)
 Debug "Address  v3 (*v3) :  " +Hex(*v3)
NOP
NOP;enough NOPs to think and watch
NOP
MOV edi,*v1 ;points to value1(value 0x1FF)(address[edi])

MOV eax,0x3ffff;a big value to show action well
LEA eax,[edi+4];eax loaded with POINTER to v2 value=2FF
MOV ebx,[eax];ebx is now loaded with 2FF
LEA ecx,[eax+4];ecx=POINTER to v3
MOV eax,[ecx-8];eax=1FF (pointer to v3 - 8)
NOP
MOV eax,[edi+4];eax=2FF 
MOV ecx,[edi+2*4];points to v3
LEA ebx,[edi];will load as a pointer (LEA)
MOV eax,[ebx+8];eax = 3FF
LEA ecx,[edi+8];ecx is now a pointer to v3
MOV eax,[ecx-8];will load value1pointed to by ecx-8
NOP; 
NOP;
gebe

Posted: Sun Jun 03, 2007 7:41 pm
by Trond
The tests
I know what it does, but it seems I'm not able to explain it easily. When I said the functionality overlaps I mean that they can do the same, but not when given the same arguments.