Ответ 1
Прежде всего, gcc
не всегда это делает. Заполнение контролируется -falign-functions
, которое автоматически включается -O2
и -O3
:
-falign-functions
-falign-functions=n
Совместите начало функций со следующей мощностью-два больше, чем
n
, пропустив доn
байт. Например,-falign-functions=32
выравнивает функции к следующей 32-байтовой границе, но-falign-functions=24
будет выравниваться только с следующей 32-байтовой границей если это можно сделать, пропустив 23 байта или меньше.
-fno-align-functions
и-falign-functions=1
эквивалентны и означают, что функции не будут выровнены.Некоторые ассемблеры поддерживают этот флаг только тогда, когда n является степенью двух; в в этом случае он округляется.
Если n не указано или равно нулю, используйте зависящее от машины значение по умолчанию.
Включено на уровнях -O2, -O3.
Для этого может быть несколько причин, но главная из них на x86, вероятно, такова:
Большинство процессоров извлекают инструкции в выровненных 16-байтных или 32-байтных блоках. Может быть выгодно выровнять записи критического цикла и подпрограммы на 16, чтобы минимизировать число 16-байтных границ в коде. В качестве альтернативы, убедитесь, что в первых нескольких инструкциях после 16-байтовой границы нет 16-байтовой границы после записи критического цикла или подпрограммы.
(Цитата из раздела "Оптимизация подпрограмм в сборке" язык "от Agner Fog.)
edit: Вот пример, демонстрирующий дополнение:
// align.c
int f(void) { return 0; }
int g(void) { return 0; }
При компиляции с использованием gcc 4.4.5 с настройками по умолчанию я получаю:
align.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <f>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: b8 00 00 00 00 mov $0x0,%eax
9: c9 leaveq
a: c3 retq
000000000000000b <g>:
b: 55 push %rbp
c: 48 89 e5 mov %rsp,%rbp
f: b8 00 00 00 00 mov $0x0,%eax
14: c9 leaveq
15: c3 retq
Задание -falign-functions
дает:
align.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <f>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: b8 00 00 00 00 mov $0x0,%eax
9: c9 leaveq
a: c3 retq
b: eb 03 jmp 10 <g>
d: 90 nop
e: 90 nop
f: 90 nop
0000000000000010 <g>:
10: 55 push %rbp
11: 48 89 e5 mov %rsp,%rbp
14: b8 00 00 00 00 mov $0x0,%eax
19: c9 leaveq
1a: c3 retq