Alex B
Alex B

Reputation: 84792

GCC function padding value

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?

Upvotes: 6

Views: 1678

Answers (3)

Unsigned
Unsigned

Reputation: 9916

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."

Upvotes: 3

R.. GitHub STOP HELPING ICE
R.. GitHub STOP HELPING ICE

Reputation: 215193

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.

Upvotes: 7

caf
caf

Reputation: 239011

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.

Upvotes: 2

Related Questions