Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GCC function padding value

Tags:

c++

c

gcc

Whenever I compile C or C++ code with optimizations enable,d GCC aligns functions to a 16-byte boundary (on IA-32). If the function is shorter than 16 bytes, GCC pads it with some bytes, which don't seem to be random at all:

19:   c3                      ret
1a:   8d b6 00 00 00 00       lea    0x0(%esi),%esi

It always seems to be either 8d b6 00 00 00 00 ... or 8d 74 26 00.

Do function padding bytes have any significance?

like image 379
Alex B Avatar asked Dec 20 '10 01:12

Alex B


3 Answers

The padding is created by the assembler, not by gcc. It merely sees a .align directive (or equivalent) and doesn't know whether the space to be padded is inside a function (e.g. loop alignment) or between functions, so it must insert NOPs of some sort. Modern x86 assemblers use the largest possible NOP opcodes with the intention of spending as few cycles as possible if the padding is for loop alignment.

Personally, I'm extremely skeptical of alignment as an optimization technique. I've never seen it help much, and it can definitely hurt by increasing the total code size (and cache utilization) tremendously. If you use the -Os optimization level, it's off by default, so there's nothing to worry about. Otherwise you can disable all the alignments with the proper -f options.

like image 181
R.. GitHub STOP HELPING ICE Avatar answered Oct 20 '22 09:10

R.. GitHub STOP HELPING ICE


The assembler first sees an .align directive. Since it doesn't know if this address is within a function body or not, it cannot output NULL 0x00 bytes, and must generate NOPs (0x90).

However:

lea    esi,[esi+0x0] ; does nothing, psuedocode: ESI = ESI + 0

executes in fewer clock cycles than

nop
nop
nop
nop
nop
nop

If this code happened to fall within a function body (for instance, loop alignment), the lea version would be much faster, while still "doing nothing."

like image 25
Unsigned Avatar answered Oct 20 '22 09:10

Unsigned


The instruction lea 0x0(%esi),%esi just loads the value in %esi into %esi - it's no-operation (or NOP), which means that if it's executed it will have no effect.

This just happens to be a single instruction, 6-byte NOP. 8d 74 26 00 is just a 4-byte encoding of the same instruction.

like image 2
caf Avatar answered Oct 20 '22 09:10

caf