#c #gcc #assembly #compilation #x86
#c #gcc #сборка #Сборник #x86
Вопрос:
Я узнаю о том, как компиляторы представляют программы на C в сборке. У меня есть вопрос о чем-то, что делает компилятор, в чем я не могу разобраться. Вот некоторый код C :
class Class1 {
public:
int i;
char ch;
};
int main() {
Class1 cls;
}
Компиляция с помощью «g -S» выводит это (я удалил все, кроме определения функции):
main:
push ebp
mov ebp, esp
sub esp, 16
mov eax, 0
leave
ret
Я не понимаю строку sub esp, 16
. Зачем ему выделять 16 байт для экземпляра этого класса, которому требуется всего 8, если учесть выравнивание и заполнение структуры данных?
Это должно быть
[int i - 4 bytes][char ch - 1 byte][padding - 3 bytes]
не так ли?
Когда я скомпилировал код с определением класса, также включающим double, т.е.
class Class1 {
public:
int i;
char ch;
double dub;
};
он по-прежнему выделял 16 байт, что имело смысл в этом случае.
Итак, почему компилятор выделяет 16 байт, когда ему нужно всего 8?
Комментарии:
1. 1 за хорошо сформулированный и хорошо проработанный вопрос!
Ответ №1:
Это связано с выравниванием стекового фрейма, а не с выравниванием структуры.
Если вы выполнили a sizeof()
для своих объектов, вы увидите, что ожидаете от выравнивания структуры и заполнения.
Однако стековые фреймы немного отличаются. В большинстве современных систем выравнивание стека составляет 16 байт (или более) для обеспечения доступа к памяти SSE.
Комментарии:
1. Это, кажется, покрывает это. Есть ли простой для объяснения ответ на вопрос, что именно представляет собой доступ к памяти SSE?
2. SSE — это набор 128-битных инструкций SIMD на x86. Регистры имеют длину 16 байт. Поэтому стек должен быть выровнен по 16 байтам. ( en.wikipedia.org/wiki/Streaming_SIMD_Extensions )