assemblyvisual-c++x86

Redundant instruction in compiled code


Possible Duplicate:
What's the point of LEA EAX, [EAX]?

During a disassembly practice, I have observed 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;
}

compiling using vc++ 2008 with optimization:

cl /Ox test.cpp

disassembly of 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 am not exactly an expert, as you can see from the example code, but I was able to figure out this assembly listing, taking into account that I wrote the original code. The only thing that bothers me is the following line:

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

Why does the compiler do that? It doesn't effect any register or flag, and it seems like a redundant code. The only thing I can think about is that the compiler aligns the code where the jmp goes to in the second loop (loc_401020) is this might be the reason?


Solution

  • Yes, it looks like it's inserting padding to align the jump target. If you use /Fa to have the compiler produce assembly output, that'll show up as npad 7, making it explicit that it's inserting padding. From there, it's up to the assembler to pick out the most efficient sequence of instructions it can find to use up the specified space while using as little CPU time as possible.