flat assembler
Message board for the users of flat assembler.

Index > Main > The most useless instruction

Goto page Previous  1, 2, 3, 4, 5, 6, 7  Next
Author
Thread Post new topic Reply to topic
bubach



Joined: 17 Sep 2004
Posts: 341
Location: Trollhättan, Sweden
bubach 29 Mar 2012, 19:54
Hi,

I'd love to get a couple of examples on where LEA is more useful than MOV? As i've read the describtion of LEA I can't seem to figure out where it's different or in what way MOV can't be used to get the same results?

Since a couple of you have mentioned it being one of the most useful instructions, and also good with 64-bit programming I assume it can operate memory addresses a bit different from what a MOV supports?

It feels like i might be embarassing myself here, but it's been quite some time since my last Assembly work and I'm rusty. Laughing
Post 29 Mar 2012, 19:54
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 19254
Location: In your JS exploiting you and your system
revolution 29 Mar 2012, 20:52
Code:
pushfd
mov eax,ecx
add eax,edx
add eax,13
popfd

; ... or instead use LEA

lea eax,[ecx+edx+13] ;a single instruction to replace the five above    
Post 29 Mar 2012, 20:52
View user's profile Send private message Visit poster's website Reply with quote
cod3b453



Joined: 25 Aug 2004
Posts: 618
cod3b453 29 Mar 2012, 22:59
@bubach: LEA is one of the most useful because it has the form "reg := reg+reg*scale+constant" allowing it to perform the triple addition revolution posted above as well as fast small constant multiplication (e.g. lea rax,[rax+2*rax] is equivalent to mul 3 but does not trash rdx); this can even be repeated for larger factors with the same benefits. In the case of 64bit code, it is the only instruction that can directly read rip (lea rax,[rip]), which is very useful when dealing with position independent code.

EDIT: I forgot to explicitly point out that while MOV performs the same address arithmetic as LEA, the result is the data at the address instead of the address.

----

All instructions have some kind of use at some point* but I'm sometimes disappointed with instructions such as pshuf for not having an encoding for a register imm8.


(*though I think quite a few are pretty redundant now Laughing)
Post 29 Mar 2012, 22:59
View user's profile Send private message Reply with quote
bubach



Joined: 17 Sep 2004
Posts: 341
Location: Trollhättan, Sweden
bubach 30 Mar 2012, 01:23
well, i'm not sure it produces the expected result but
Code:
mov eax,[ecx+edx+13]    

assembles without error too. and data at the address versus the address point, i thought that was just as simple as using [] ? which you apparently do on LEA anyway? now flags is another subject, and i can see a reason for not wanting to mess that up, but unless i'm missing something, you can do the exact same thing with MOV in one line? the rip thing was a cool trick though, didn't know that.
Post 30 Mar 2012, 01:23
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 19254
Location: In your JS exploiting you and your system
revolution 30 Mar 2012, 01:53
bubach wrote:
well, i'm not sure it produces the expected result but
Code:
mov eax,[ecx+edx+13]    

assembles without error too. and data at the address versus the address point, i thought that was just as simple as using [] ? which you apparently do on LEA anyway? now flags is another subject, and i can see a reason for not wanting to mess that up, but unless i'm missing something, you can do the exact same thing with MOV in one line? the rip thing was a cool trick though, didn't know that.
I think you missed the point.
Post 30 Mar 2012, 01:53
View user's profile Send private message Visit poster's website Reply with quote
bubach



Joined: 17 Sep 2004
Posts: 341
Location: Trollhättan, Sweden
bubach 30 Mar 2012, 02:14
yeah i guessed as much Laughing
Post 30 Mar 2012, 02:14
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 19254
Location: In your JS exploiting you and your system
revolution 30 Mar 2012, 02:19
Instead of thinking about memory addresses, think of it as numerical computations. Let's say we want to compute x = y * 8 + z.

Naive way (ignoring eflags changes):
Code:
;eax=y
;edx=z
;ecx=x (our answer)
mov ecx,eax ;x = y
shl ecx,3 ;x = y * 8
add ecx,edx ;x = y * 8 + z    
The LEA way:
Code:
;eax=y
;edx=z
;ecx=x (our answer)
lea ecx,[eax*8+edx] ;x = y * 8 + z    
Post 30 Mar 2012, 02:19
View user's profile Send private message Visit poster's website Reply with quote
Picnic



Joined: 05 May 2007
Posts: 1309
Location: Paradise Falls
Picnic 30 Mar 2012, 06:41
bubach, LEA can do a shift operation, two additions, and a move in just one instruction.

Example:
Code:
mov eax, ecx
shl eax, 3
add eax, ebx
sub eax, 1000
    

The LEA way:
Code:
lea eax, [ebx+8*ecx-1000]
    
Post 30 Mar 2012, 06:41
View user's profile Send private message Reply with quote
16bitPM



Joined: 08 Jul 2011
Posts: 30
16bitPM 30 Mar 2012, 18:20
A somewhat simpler way to look at it is to see LEA as a 3-operand add:

Replace:

MOV EAX,EBX
ADD EAX,17 // ADD EAX,ESI

With:
LEA EAX,[EBX+17] // LEA EAX,[EBX+ESI]

(reg1 = reg2 +constant // reg1=reg2+reg3)
Post 30 Mar 2012, 18:20
View user's profile Send private message Reply with quote
bubach



Joined: 17 Sep 2004
Posts: 341
Location: Trollhättan, Sweden
bubach 31 Mar 2012, 00:06
well, the thing is.. each one of these assembles fine ine fasw

Code:
mov ecx,[eax*8+edx]  ; same byte size as LEA, works fine to assemble
mov eax, [ebx+8*ecx-1000]  ; same byte size as LEA, assembles fine too    


So is there a problem with fasm, does it allow MOV instructions that isn't really supported? :s Becasue I'm still waiting for an example of LEA instruction where it won't assemble if I simply switch to MOV instead... :/
Post 31 Mar 2012, 00:06
View user's profile Send private message Reply with quote
gunblade



Joined: 19 Feb 2004
Posts: 209
gunblade 31 Mar 2012, 01:23
As cod3b453 said:
Quote:

I forgot to explicitly point out that while MOV performs the same address arithmetic as LEA, the result is the data at the address instead of the address.

LEA carries out the arithmetic in the brackets, and puts the resulting ADDRESS in eax.. whereas MOV carries out the arithmetic in the brackes, and puts the DATA at the address calculated in eax..

In C(-ish) syntax it would be something similar to:

Code:
eax = ebx+8*ecx-1000;       // Equivalent of: lea eax, [ebx+8*ecx-1000]
eax = *(ebx+8*ecx-1000);       // Equivalent of: mov eax, [ebx+8*ecx-1000]    


Last edited by gunblade on 31 Mar 2012, 01:33; edited 2 times in total
Post 31 Mar 2012, 01:23
View user's profile Send private message Reply with quote
tripledot



Joined: 06 Jan 2009
Posts: 49
tripledot 31 Mar 2012, 01:25
@bulbach:

Sooner or later you're going to try writing a program, and God help us all.


Last edited by tripledot on 31 Mar 2012, 01:50; edited 1 time in total
Post 31 Mar 2012, 01:25
View user's profile Send private message Reply with quote
bubach



Joined: 17 Sep 2004
Posts: 341
Location: Trollhättan, Sweden
bubach 31 Mar 2012, 01:40
no thats not it, what i try to understand if, what if i do

Code:
mov eax, ebx+8*ecx-1000    


then it should be the same? maybe that's not valid syntax, in that case i see a point. drunk now too, hard to make sense of a lighter even.. hahah Razz
Post 31 Mar 2012, 01:40
View user's profile Send private message Reply with quote
tripledot



Joined: 06 Jan 2009
Posts: 49
tripledot 31 Mar 2012, 01:48
Code:
foo db 5

mov eax, foo   ; eax = address of foo (could be anything, e.g. 48765098)
mov eax, [foo] ; eax = value of foo (i.e. 5)

lea eax, foo   ; invalid syntax
lea eax, [foo] ; same as "mov eax, foo", i.e. calculates the ADDRESS of foo, NOT its value

mov eax, foo ; eax = address of foo (e.g. 230)
add eax, 100 ; eax = address of foo + 100 (in this case 330)

; the VALUE of foo is still equal to 5!!!

lea eax, [foo+100] ; same as the previous two instructions
    


I can't be arsed anymore.
Post 31 Mar 2012, 01:48
View user's profile Send private message Reply with quote
ProphetOfDoom



Joined: 08 Aug 2008
Posts: 120
Location: UK
ProphetOfDoom 31 Mar 2012, 02:12
I think the syntax of the LEA instruction is misleading because the square brackets imply dereferencing (like the C language's unary * operator) when really no dereferencing is taking place. No wonder people get confused.
Post 31 Mar 2012, 02:12
View user's profile Send private message Reply with quote
bubach



Joined: 17 Sep 2004
Posts: 341
Location: Trollhättan, Sweden
bubach 31 Mar 2012, 02:18
ok thanks got it now. didn't kniw something like "mov eax, foo+100" was invalid sybtax. and i'm just getting more drunk, must stop posting before i annoy you to much Razz
Post 31 Mar 2012, 02:18
View user's profile Send private message Reply with quote
16bitPM



Joined: 08 Jul 2011
Posts: 30
16bitPM 31 Mar 2012, 10:43
tripledot wrote:
@bulbach:

Sooner or later you're going to try writing a program, and God help us all.


LOL
Post 31 Mar 2012, 10:43
View user's profile Send private message Reply with quote
16bitPM



Joined: 08 Jul 2011
Posts: 30
16bitPM 31 Mar 2012, 10:51
bubach wrote:
ok thanks got it now. didn't kniw something like "mov eax, foo+100" was invalid sybtax. and i'm just getting more drunk, must stop posting before i annoy you to much Razz


It's not invalid syntax. If foo is a symbol then the assembler will do the calculation for you. You are misled because the different syntax:

MOV EAX,EBX+4*ECX+1000H → INVALID!! Assembler can't know contents of registers.

MOV EAX,[EBX+4*ECX+1000H] → VALID! CPU calculates address and dereferences that pointer.

MOV EAX,offset_table + 100H → VALID! Assembler knows contents of symbol 'offset_table'.

Now, internally, the CPU uses a so-called SIB-byte to encode this mode: Scale-Index-Byte offset. Suppose you want an instruction which ONLY did the calculation and move the result in your register... then you'd need a SIB-byte.
Memory references are represented by square brackets which are coded with addressing mode bits and/or SIB-bytes. So... the easiest is just to retain the syntax with brackets. Hence the instruction:

LEA EAX,[EBX+4*ECX+1000H]

uses an SIB byte... but not to use it as a pointer!

It may come as a relevation for you that earlier versions of MASM (prior to 6.0) implicitly changed

LEA reg,[reg] to MOV reg,reg and
LEA reg,[addr] to MOV reg,addr

Hope this helps Smile

---

In the meantime in geekland: who *ever* used CMC?
Post 31 Mar 2012, 10:51
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1509
Location: Toronto, Canada
AsmGuru62 31 Mar 2012, 11:21
I always use CMC.
You see, I got a habit of making BOOLEAN functions return Carry Flag as a TRUE/FALSE indicator. And sometimes, CF is the opposite of a result, so I just CMC it before return.

Smile
Post 31 Mar 2012, 11:21
View user's profile Send private message Send e-mail Reply with quote
16bitPM



Joined: 08 Jul 2011
Posts: 30
16bitPM 31 Mar 2012, 11:42
AsmGuru62 wrote:
I always use CMC.
You see, I got a habit of making BOOLEAN functions return Carry Flag as a TRUE/FALSE indicator. And sometimes, CF is the opposite of a result, so I just CMC it before return.

Smile


If I would have a beard, I would scratch it.
Weird that I didn't think of this Embarassed
Post 31 Mar 2012, 11:42
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page Previous  1, 2, 3, 4, 5, 6, 7  Next

< 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-2023, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.

Website powered by rwasa.