flat assembler
Message board for the users of flat assembler.

Index > Main > Whats the difference between lea and mov...

Author
Thread Post new topic Reply to topic
mikokawasaki



Joined: 28 Nov 2012
Posts: 12
mikokawasaki 21 Oct 2013, 03:53
Aren't these three statements the same thing or are they different in some way? Confused


Code:
mov eax, var

mov eax, addr var

lea eax, [var]

    
Post 21 Oct 2013, 03:53
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20453
Location: In your JS exploiting you and your system
revolution 21 Oct 2013, 04:30
The form with addr is only valid by use of the pushd macro (used by the invoke/stdcall/ccall macros).

The other two produce different length encodings. LEA is usually longer than MOV.

As to what happens inside the CPU is anyone's guess. They might use different execution units, or not, depending upon which make/model of CPU is used. But the end result is the same as far as the final value placed into the eax register.
Post 21 Oct 2013, 04:30
View user's profile Send private message Visit poster's website Reply with quote
l_inc



Joined: 23 Oct 2009
Posts: 881
l_inc 21 Oct 2013, 10:24
mikokawasaki
There's a functional difference in 64 bit mode. lea by default gets compiled into a rip-relative opcode and this way does not require a fixup if specified. On the other hand mov has the absolute address encoded and therefore is not base independent for "bound" data.

_________________
Faith is a superposition of knowledge and fallacy
Post 21 Oct 2013, 10:24
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20453
Location: In your JS exploiting you and your system
revolution 21 Oct 2013, 10:32
If you are using "lea eax,[var]" in 64-bit code then you had better hope your code is never put above the 4G address range.

[rant] I'm still upset at AMD for allowing 32-bit values to be addresses in 64-bit mode. [/rant]
Post 21 Oct 2013, 10:32
View user's profile Send private message Visit poster's website Reply with quote
l_inc



Joined: 23 Oct 2009
Posts: 881
l_inc 21 Oct 2013, 11:41
revolution
Yes, but this instruction is still correct, and you're free to generalize my remark for other registers including 64bit wide. Smile

_________________
Faith is a superposition of knowledge and fallacy
Post 21 Oct 2013, 11:41
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1671
Location: Toronto, Canada
AsmGuru62 21 Oct 2013, 14:44
I would also note that if address of local variable is to be loaded into a register -- the proper way is to use LEA and not MOV.
Post 21 Oct 2013, 14:44
View user's profile Send private message Send e-mail Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20453
Location: In your JS exploiting you and your system
revolution 21 Oct 2013, 14:54
AsmGuru62 wrote:
I would also note that if address of local variable is to be loaded into a register -- the proper way is to use LEA and not MOV.
Local variables cannot use MOV and will give an assembly error.
Post 21 Oct 2013, 14:54
View user's profile Send private message Visit poster's website Reply with quote
mikokawasaki



Joined: 28 Nov 2012
Posts: 12
mikokawasaki 21 Oct 2013, 15:47
i understand mov is absolute addressing...

but for lea..

so if "var dd ?" is at 0x4000... and "lea eax, [var]" is at 0x4015...

then eax is equal to "-15" ?


i dont know if this is correct...
Post 21 Oct 2013, 15:47
View user's profile Send private message Reply with quote
l_inc



Joined: 23 Oct 2009
Posts: 881
l_inc 21 Oct 2013, 19:03
mikokawasaki
Quote:
then eax is equal to "-15"

No. And you created so many mistakes with this statement, that it's quite hard to build a correct answer.

Firstly, eax will have the value "0x4000..." whatever the triple dot means. This fact is enough to invalidate all further corrections I'm going to provide.
Secondly, subtraction 0x4000-0x4015 results in -0x15, not in -15.
Thirdly, relative value should be calculated from the end of an instruction. E.g., "0x4000..." - ("0x4015..." + 6).
Fourthly, if you use triple dot, one would most likely assume, that the address value continues, in which case the relative value should be much larger (in its absolute value) then 15 or 0x15.

Quote:
i understand mov is absolute addressing...

If I continued nitpicking, then I'd say, that absolute addressing is mov eax, [var], but mov eax, var is normally called immediate addressing. Btw. remember, that this is true in the context of fasm, but not necessarily in the context of other x86 assembler compilers. In particular in case of masm syntax both notations mean the same instruction with absolute addressing.

Quote:
but for lea..

Both mov and lea result in eax containing the same value under normal circumstances. The difference is the instruction encoding. In 16 and 32 bit modes both will even have the address of var encoded directly in the instruction.

In 64 bit mode if absolute addressing is not enforced, then lea is encoded with rip-relative addressing. Thus if var is located at address 0x4000 and the instruction is located at address 0x4015, then lea eax,[var] will consist of a two-bytes opcode and a four-bytes rip-relative offset equal to 0x4000-(0x4015+6) = -0x1B = 0xFFFFFFE5 . mov eax,var in turn will consist of a one-byte opcode and a four-bytes absolute address value equal to 0x00004000 . But in both cases eax will obtain the value 0x4000 during runtime. Unless (!) you compile the instruction with 0x4015 base address, and load it at some other address. In this case mov will put 0x4000 into eax, but lea will put (some_other_address+6-0x1B).

_________________
Faith is a superposition of knowledge and fallacy
Post 21 Oct 2013, 19:03
View user's profile Send private message Reply with quote
mikokawasaki



Joined: 28 Nov 2012
Posts: 12
mikokawasaki 23 Oct 2013, 16:13
sorry about that l_inc, the triple dot thing is something i do naturally to break statements visually, ill be more careful next time i do something like that...

i understand now, what is going on, it took me 2 days to understand what you were trying to tell me and i had no idea the instructions we type in assembly gets 'further' encoded...

is there a way to test assembly instructions and see how they get encoded.. so i can learn what each instruction does..like a play-around sandbox..

_________________
if you "think you can" or "think you can't"... you're right...
Post 23 Oct 2013, 16:13
View user's profile Send private message Reply with quote
dogman



Joined: 18 Jul 2013
Posts: 114
dogman 23 Oct 2013, 16:21
mikokawasaki wrote:
i understand now, what is going on, it took me 2 days to understand what you were trying to tell me and had i no idea the instructions we type in assembly gets 'further' encoded...


That is not typical, but Intel does a lot of bizarre twisted stuff. There is not the usual one-to-one correspondence between Intel assembly instructions and opcodes etc. that exists on most other platforms. The addressing modes also seem to be more numerous and complicated than most others.

mikokawasaki wrote:
is there a way to test assembly instructions and see how they get encoded.. so i can learn how Assembly works internally..like a play-around sandbox


Sure, just start coding! Seriously, code a test instruction and use fasm and nasm and whatever else and see what you get for one line of code. It doesn't have to be able to run for you to assemble it.

But I don't think you're going to learn too much from this exercise because Intel encoding is so unnecessarily complicated. If you want to write an assembler or debugger obviously you need to get into this. If you want to be able to write Intel code I don't think you really need to know it unless you come across a bug in the assembler(s) you use.

If you're just interested in learning assembly coding in general and not specifically Intel (although for most people Intel is the most useful) there are other architectures that are much simpler, and you can use various emulators and simulators to write and run code with.

_________________
Sources? Ahahaha! We don't need no stinkin' sources!


Last edited by dogman on 23 Oct 2013, 16:26; edited 1 time in total
Post 23 Oct 2013, 16:21
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20453
Location: In your JS exploiting you and your system
revolution 23 Oct 2013, 16:23
l_inc wrote:
Unless (!) you compile the instruction with 0x4015 base address, and load it at some other address. In this case mov will put 0x4000 into eax, but lea will put (some_other_address+6-0x1B) ...
... and unless you are using a file format with relocations active and then again both mov and lea will give the same result of the new location.
Post 23 Oct 2013, 16:23
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.