Прежде всего, 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-байтовой границы.
(Цитируется из «Оптимизация подпрограмм на языке ассемблера» Агнера Фога)
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