Redundant instruction in compiled code

Possible duplicate:
What is the meaning of LEA EAX, [EAX]?

During disassembly practice, I noticed the following code:

test.cpp:

#include <stdio.h> int main(int argc, char * argv[]) { for (int i = 0; i < 10 ; ++i) { printf("%i\n", i); } int i = 0; while ( i < 10) { printf("%i\n", i); ++i; } return 0; } 

compilation using vC ++ 2008 with optimization:

 cl /Ox test.cpp 

dismantling the main function:

 .text:00401000 var_4 = dword ptr -4 ; BTW, IDA fails to see that esi is pushed to save it, not to allocate space to local variable .text:00401000 .text:00401000 push esi .text:00401001 xor esi, esi .text:00401003 .text:00401003 loc_401003: ; CODE XREF: sub_401000+15j .text:00401003 push esi .text:00401004 push offset byte_40A150 .text:00401009 call sub_401038 ; printf .text:0040100E inc esi .text:0040100F add esp, 8 .text:00401012 cmp esi, 0Ah .text:00401015 jl short loc_401003 .text:00401017 xor esi, esi .text:00401019 lea esp, [esp+0] .text:00401020 .text:00401020 loc_401020: ; CODE XREF: sub_401000+32j .text:00401020 push esi .text:00401021 push offset unk_40A154 .text:00401026 call sub_401038 ; printf .text:0040102B inc esi .text:0040102C add esp, 8 .text:0040102F cmp esi, 0Ah .text:00401032 jl short loc_401020 .text:00401034 xor eax, eax .text:00401036 pop esi .text:00401037 retn 

Now I'm not quite an expert, as you can see from the example code, but I was able to figure out this list of assemblies, given that I wrote the source code. The only thing that bothers me is the following line:

 .text:00401019 lea esp, [esp+0] 

Why does the compiler do this? It does not affect any register or flag, and it looks like redundant code. The only thing I can think of is that the compiler aligns the code in which jmp is in the second loop (loc_401020), could this be the reason?

+7
source share
3 answers

Yes, it seems that the pad insert aligns the transition target. If you use /Fa for the compiler to build, it will display as npad 7 , which makes it obvious that it is inserting a pad. From there, down to assembler, select the most efficient sequence of instructions that it can find in order to use the specified space, using as little processor time as possible.

+3
source

The useless instruction is immediately before the mark, and the mark is aligned. For me it looks like nop (assemblers can generate one nop command of different lengths, because it is more efficient than several "standard" single-byte nop , when execution should go through them).

+1
source

Your guess is correct. This command is actually a 7-byte NOP to align the label at the beginning of the loop to a 16-byte boundary. If you looked at the actual encoding of this command, you would probably notice that this not only does not affect any register or flag, but also uses a 4-byte encoding to immediately offset 0, when it can just as easily use more short coding. All this is to consume the correct number of bytes of code, making the instruction as efficient as possible for execution.

+1
source

All Articles