Mam kompilacji następującą prostą funkcję pokazową:Dlaczego GCC generuje instrukcje dotyczące przechowywania stosów, gdy nie są one potrzebne?
int add(int a, int b) {
return a + b;
}
Oczywiście funkcja ta będzie inlined, ale załóżmy, że to dynamicznie połączone lub nie inlined z jakiegoś innego powodu. Z wyłączony optymalizacji kompilator produkuje oczekiwany kod:
00000000 <add>:
0: 55 push ebp
1: 89 e5 mov ebp,esp
3: 8b 45 0c mov eax,DWORD PTR [ebp+0xc]
6: 03 45 08 add eax,DWORD PTR [ebp+0x8]
9: 5d pop ebp
a: c3 ret
Ponieważ istnieje żadna funkcja zwraca wewnątrz tej funkcji, instrukcja 0, 1 i 9 pozornie nie mają celu. Ponieważ optymalizacja jest wyłączona, jest to dopuszczalne.
Jednak podczas kompilacji przy optymalizacji pod kątem rozmiaru z -Os -s
tworzony jest dokładnie ten sam kod. Wydaje się raczej nieekonomiczne zwiększenie rozmiaru funkcji o 66% dzięki tym opcjom.
Dlaczego kod nie jest zoptymalizowany pod kątem poniższych?
00000000 <add>:
0: 8b 45 0c mov eax,DWORD PTR [esp+0x8]
3: 03 45 08 add eax,DWORD PTR [esp+0x4]
6: c3 ret
Czy kompilator po prostu nie warto rozważyć tę optymalizację, czy jest to związane z innymi szczegółami, jak wyrównanie funkcji?
Istnieje również możliwość, że jest to środek bezpieczeństwa przeciwko pewnym atakom szturmowym stosu. –
@MarcB Myślisz o "kanarkach stosowych", które wyglądają inaczej. Wskaźniki ramek niestety nie pomagają w walce na stosie. – zwol