flat assembler
Message board for the users of flat assembler.

Index > Main > Error when using the lea instruction?

Goto page 1, 2  Next
Author
Thread Post new topic Reply to topic
Mino



Joined: 14 Jan 2018
Posts: 163
Mino 22 Aug 2018, 15:59
Hello,
I try to make a simple optimized function of adding two values. Something close to this in C :

Code:
int add(int a, int b) {
    return a + b;
}
    


I tried to use the lea instruction as follows:

Code:
add:
        lea     eax, [esi+edi]
        ret
    


But of course I had an error.

After I documented, I realized that it was the size of the registers that I used that was not adapted.
However, here is what it looks like with GCC (with the optimization option). The same as me...

Could you explain to me why it works with GCC, but not with me?

_________________
The best way to predict the future is to invent it.


Last edited by Mino on 22 Aug 2018, 16:32; edited 1 time in total
Post 22 Aug 2018, 15:59
View user's profile Send private message Reply with quote
CandyMan



Joined: 04 Sep 2009
Posts: 414
Location: film "CandyMan" directed through Bernard Rose OR Candy Shop
CandyMan 22 Aug 2018, 16:13
what is "eci"
did you mean?
Code:
lea eax,[esi+edi]    
or define
Code:
eci:
...
lea eax,[eci+edi]    

_________________
smaller is better
Post 22 Aug 2018, 16:13
View user's profile Send private message Reply with quote
Mino



Joined: 14 Jan 2018
Posts: 163
Mino 22 Aug 2018, 16:32
Yes, excuse me: a typo Very Happy
This is just :
Code:
lea eax,[esi+edi]
    
Post 22 Aug 2018, 16:32
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20418
Location: In your JS exploiting you and your system
revolution 22 Aug 2018, 17:56
I suspect the problem is that you are trying to define a label "add". Rename the label to something else, the LEA instruction is fine.
Post 22 Aug 2018, 17:56
View user's profile Send private message Visit poster's website Reply with quote
DimonSoft



Joined: 03 Mar 2010
Posts: 1228
Location: Belarus
DimonSoft 22 Aug 2018, 18:00
Should also note here that such a procedure might not give any performance gain since the overhead of calling a procedure plus depending on these particular registers might be greater than the possible gain. Even with modern optimizing hardware I really doubt you’ll even notice any gain, and I’d even bet that you’ll see performance loss when measured.
Post 22 Aug 2018, 18:00
View user's profile Send private message Visit poster's website Reply with quote
Mino



Joined: 14 Jan 2018
Posts: 163
Mino 22 Aug 2018, 20:21
Thanks for your answers, they helped me indirectly, but I would have taken more time to realize it Smile
The problem was that the value I sent to the esi and edi registers did not match the size of the registers and the operands (since a variable was actually pointed to in memory).

DimonSoft wrote:
Should also note here that such a procedure might not give any performance gain since the overhead of calling a procedure plus depending on these particular registers might be greater than the possible gain. Even with modern optimizing hardware I really doubt you’ll even notice any gain, and I’d even bet that you’ll see performance loss when measured.


Really? However GCC (which is not just any compiler) optimizes this operation with this code though... What would be the best way to optimize this type of procedure in your opinion?

_________________
The best way to predict the future is to invent it.
Post 22 Aug 2018, 20:21
View user's profile Send private message Reply with quote
DimonSoft



Joined: 03 Mar 2010
Posts: 1228
Location: Belarus
DimonSoft 23 Aug 2018, 07:13
Mino wrote:
The problem was that the value I sent to the esi and edi registers did not match the size of the registers and the operands (since a variable was actually pointed to in memory).

What variable in memory? The instruction has nothing to do with memory access at all.

Quote:
Really? However GCC (which is not just any compiler) optimizes this operation with this code though... What would be the best way to optimize this type of procedure in your opinion?

Optimizes adddition of two values in registers to a separate procedure consisting of one instruction plus RET?

Or a function written to just add two values passed to it? With what command-line parameters related to optimization?

Or optimizes addition of two values in registers with this particular instruction? Then what made you think it would be faster in a non-inline manner?
Post 23 Aug 2018, 07:13
View user's profile Send private message Visit poster's website Reply with quote
Mino



Joined: 14 Jan 2018
Posts: 163
Mino 23 Aug 2018, 09:57
DimonSoft wrote:

Or optimizes addition of two values in registers with this particular instruction? Then what made you think it would be faster in a non-inline manner?


Oh, I don't know, I probably would have done it in two separate instructions, but this "optimization", it was GCC that gave it.

_________________
The best way to predict the future is to invent it.
Post 23 Aug 2018, 09:57
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20418
Location: In your JS exploiting you and your system
revolution 23 Aug 2018, 10:27
LEA is a badly named instruction IMO.

It leaks the implementation details of the original 8086 CPU. Great if you are a CPU design engineer. Terrible if you are an assembly programmer.

Better would be a three operand ADD instruction.
Code:
add eax,esi,edi ;<--- lea eax,[esi+edi]    
But with the difference that the flags register is not updated when compared to the normal two operand ADD.
Post 23 Aug 2018, 10:27
View user's profile Send private message Visit poster's website Reply with quote
DimonSoft



Joined: 03 Mar 2010
Posts: 1228
Location: Belarus
DimonSoft 23 Aug 2018, 12:10
Mino wrote:
DimonSoft wrote:

Or optimizes addition of two values in registers with this particular instruction? Then what made you think it would be faster in a non-inline manner?


Oh, I don't know, I probably would have done it in two separate instructions, but this "optimization", it was GCC that gave it.

You say you don’t know but in the same sentence you say GCC gave it to you. So, I guess, you took a look at the disassembly of what GCC had generated.

My question is technically the same as…

You saw that someone uses ++i instead of i++ in C for loops, presumably for some valid reasons, not personal preference:
Code:
for (int i = 0; i < N; ++i)
  ...    
What made you think ++i would be as good when used in a while loop being wrapped in a dozen of procedures?
Code:
void RealIncrement(int **ppInt)
{
  ++(**ppInt);
}

void Increment(int *pInt)
{
  RealIncrement(&pInt);
}

i = 0;
while (i < N)
{
  ...
  Increment(&i);
}    
Post 23 Aug 2018, 12:10
View user's profile Send private message Visit poster's website Reply with quote
DimonSoft



Joined: 03 Mar 2010
Posts: 1228
Location: Belarus
DimonSoft 23 Aug 2018, 12:17
revolution wrote:
LEA is a badly named instruction IMO.

It leaks the implementation details of the original 8086 CPU. Great if you are a CPU design engineer. Terrible if you are an assembly programmer.

Better would be a three operand ADD instruction.
Code:
add eax,esi,edi ;<--- lea eax,[esi+edi]    
But with the difference that the flags register is not updated when compared to the normal two operand ADD.

But that would require changes in machine code format for this instruction and, probably, for other instructions as well. And it might not be 8086, it might be one of its predecessors. Say, BX in 8086 is said to be made up of two registers (H and L) in 8080: Why does the x86 have so few registers?. And certain backward compatibility might also be the case with the number of operands.
Post 23 Aug 2018, 12:17
View user's profile Send private message Visit poster's website Reply with quote
Mino



Joined: 14 Jan 2018
Posts: 163
Mino 23 Aug 2018, 13:35
DimonSoft wrote:

You say you don’t know but in the same sentence you say GCC gave it to you. So, I guess, you took a look at the disassembly of what GCC had generated.


Yes, indeed, but by that I meant I don't know if it's a "real" optimization from what you seem to be saying.

All I'm trying to do is give the best assembler code possible for my compiler (which I'm creating), and while I'm at it, try to optimize it to the maximum.

_________________
The best way to predict the future is to invent it.
Post 23 Aug 2018, 13:35
View user's profile Send private message Reply with quote
DimonSoft



Joined: 03 Mar 2010
Posts: 1228
Location: Belarus
DimonSoft 23 Aug 2018, 15:20
Mino wrote:
DimonSoft wrote:

You say you don’t know but in the same sentence you say GCC gave it to you. So, I guess, you took a look at the disassembly of what GCC had generated.


Yes, indeed, but by that I meant I don't know if it's a "real" optimization from what you seem to be saying.

All I'm trying to do is give the best assembler code possible for my compiler (which I'm creating), and while I'm at it, try to optimize it to the maximum.

If you need to optimize on a per-instruction basis, you might be doing something wrong by choosing C as your language. The language is too high-level for that.

I still don’t get: has GCC really generated a separate procedure with a single LEA instruction?
Post 23 Aug 2018, 15:20
View user's profile Send private message Visit poster's website Reply with quote
Furs



Joined: 04 Mar 2016
Posts: 2543
Furs 23 Aug 2018, 15:39
Mino wrote:
Really? However GCC (which is not just any compiler) optimizes this operation with this code though... What would be the best way to optimize this type of procedure in your opinion?
Inline the function.

revolution wrote:
LEA is a badly named instruction IMO.

It leaks the implementation details of the original 8086 CPU. Great if you are a CPU design engineer. Terrible if you are an assembly programmer.

Better would be a three operand ADD instruction.
Code:
add eax,esi,edi ;<--- lea eax,[esi+edi]    
But with the difference that the flags register is not updated when compared to the normal two operand ADD.
Nah, even ignoring 16-bit addressing (which has more limitations), you also have scale so add eax,esi,edi*4 and so on would have to work. And esp can't be used as index. etc.

Same rules as memory addressing so lea is ok.
Post 23 Aug 2018, 15:39
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20418
Location: In your JS exploiting you and your system
revolution 23 Aug 2018, 17:35
DimonSoft wrote:
revolution wrote:
LEA is a badly named instruction IMO.

It leaks the implementation details of the original 8086 CPU. Great if you are a CPU design engineer. Terrible if you are an assembly programmer.

Better would be a three operand ADD instruction.
Code:
add eax,esi,edi ;<--- lea eax,[esi+edi]    
But with the difference that the flags register is not updated when compared to the normal two operand ADD.

But that would require changes in machine code format for this instruction and, probably, for other instructions as well. And it might not be 8086, it might be one of its predecessors. Say, BX in 8086 is said to be made up of two registers (H and L) in 8080: Why does the x86 have so few registers?. And certain backward compatibility might also be the case with the number of operands.
It doesn't require any changes to the hardware. The capability is already there. It is just a change in the text we type to tell the assembler which instruction we wanted.
Furs wrote:
revolution wrote:
LEA is a badly named instruction IMO.

It leaks the implementation details of the original 8086 CPU. Great if you are a CPU design engineer. Terrible if you are an assembly programmer.

Better would be a three operand ADD instruction.
Code:
add eax,esi,edi ;<--- lea eax,[esi+edi]    
But with the difference that the flags register is not updated when compared to the normal two operand ADD.
Nah, even ignoring 16-bit addressing (which has more limitations), you also have scale so add eax,esi,edi*4 and so on would have to work. And esp can't be used as index. etc.

Same rules as memory addressing so lea is ok.
Fair enough. Then we can change ADD to COMPUTE, or whatever. But using LEA with the brackets is not the best way to do it IMO.
Post 23 Aug 2018, 17:35
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8356
Location: Kraków, Poland
Tomasz Grysztar 23 Aug 2018, 17:50
revolution wrote:
Fair enough. Then we can change ADD to COMPUTE, or whatever. But using LEA with the brackets is not the best way to do it IMO.
You are probably not a fan of what they did with MPX then? Wink
Post 23 Aug 2018, 17:50
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20418
Location: In your JS exploiting you and your system
revolution 23 Aug 2018, 17:59
Tomasz Grysztar wrote:
revolution wrote:
Fair enough. Then we can change ADD to COMPUTE, or whatever. But using LEA with the brackets is not the best way to do it IMO.
You are probably not a fan of what they did with MPX then? Wink
I'm actually mostly okay with that because the values used are genuinely addresses with no other purpose. No computation is involved.
Post 23 Aug 2018, 17:59
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8356
Location: Kraków, Poland
Tomasz Grysztar 23 Aug 2018, 18:22
revolution wrote:
Tomasz Grysztar wrote:
revolution wrote:
Fair enough. Then we can change ADD to COMPUTE, or whatever. But using LEA with the brackets is not the best way to do it IMO.
You are probably not a fan of what they did with MPX then? Wink
I'm actually mostly okay with that because the values used are genuinely addresses with no other purpose. No computation is involved.
In case of BNDSTX/BNDLDX the index portion of SIB is an additional data operand that does not necessarily have to be a valid pointer, just like the values used in LEA do not have to be actual addresses.
Post 23 Aug 2018, 18:22
View user's profile Send private message Visit poster's website Reply with quote
Mino



Joined: 14 Jan 2018
Posts: 163
Mino 23 Aug 2018, 19:39
DimonSoft wrote:

I still don’t get: has GCC really generated a separate procedure with a single LEA instruction?

Yes, look here Wink

_________________
The best way to predict the future is to invent it.
Post 23 Aug 2018, 19:39
View user's profile Send private message Reply with quote
DimonSoft



Joined: 03 Mar 2010
Posts: 1228
Location: Belarus
DimonSoft 24 Aug 2018, 07:48
Mino wrote:
DimonSoft wrote:

I still don’t get: has GCC really generated a separate procedure with a single LEA instruction?

Yes, look here Wink

What optimization parameters are used? What corrections to the source code does the online tool do?
Post 24 Aug 2018, 07:48
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:  
Goto page 1, 2  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-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.