Does GCC generate useless instructions?

BOOL32 doStuff() { return TRUE; } 

gcc 2.95 for vxworks 5.x by compiling the above code with -O0 for the 32-bit x86 generated by the following code:

  doStuff: 0e9de190: push %ebp 0e9de191: mov %esp,%ebp 308 return TRUE; 0e9de193: mov $0x1,%eax 0e9de198: jmp 0xe9de1a0 <doStuff+16> 312 { 0e9de19a: lea 0x0(%esi),%esi // The JMP jumps here 0e9de1a0: mov %ebp,%esp 0e9de1a2: pop %ebp 0e9de1a3: ret 

Everything looks fine before the JMP and LEA commands. What are they needed for?


I suppose this is some kind of alignment, but I'm not sure about that.

I would do something like this:

  doStuff: 0e9de190: push %ebp 0e9de191: mov %esp,%ebp 308 return TRUE; 0e9de193: mov $0x1,%eax 0e9de1XX: mov %ebp,%esp 0e9de1XX: pop %ebp 0e9de1XX: ret 0e9de1XX: fill with lea 0x0, %esi 
+5
source share
1 answer

lea 0x0(%esi),%esi is a long NOP, and jmp jumps over it. You probably have a version of ancient binutils (containing as ) for your old version of gcc.

So, when gcc put a .p2align to align the label in the middle of a function that would not otherwise be a branch target (for some bizarre reason, but it's -O0, so it doesn't even have to be good code) the assembler made a long NOP and jumped through him.

Usually you only go through the NOP block if there were a lot of them, especially if they were single-byte NOPs. This is really dumb code, so don't use such hard tools. You can try updating your assembler (but use gcc2.95 if you need to). Or check that this does not happen with -O2 or -O3 , in which case it does not matter.

If for some reason you need to continue to use gcc2.95, then just know that it is ancient, and this is part of the compromise that you make to continue to use what it makes you use.

+8
source

All Articles