Why GCC compiler adds this three lines when using double and don't when there is Int?
With int:
#include <cstdio>
int main(){
int i = 1;
}
==>
main:
push ebp
mov ebp, esp
sub esp, 16
mov DWORD PTR [ebp-4], 1
mov eax, 0
leave
ret
With double:
#include <cstdio>
int main(){
double i = 1;
}
==>
main:
lea ecx, [esp+4] // This three lines
and esp, -8 // ...
push DWORD PTR [ecx-4] // ...
push ebp
mov ebp, esp
push ecx
sub esp, 20
fld1
fstp QWORD PTR [ebp-16]
mov eax, 0
add esp, 20
pop ecx
pop ebp
lea esp, [ecx-4]
ret
Similar happens when using pointers, for example, int *s = new int(4);
Can you explain why this happens, and why not always?
In the case of a double
in automatic scope (on the stack), the extra code aligns the stack frame at an even 8 byte boundary, so that the double
variable is stored at a memory address with suitable alignment. The stack pointer, when entering the function, is not guaranteed to be aligned on an even 8-byte boundary, and the compiler adds the extra code to make it so.
That's what the and esp, -8
does. -8 is 0xFFFFFFF8. This clears the last 3 bits of esp
, using and
, making it point to an even 8 byte boundary memory address, adjusting it down (the stack grows from high to low memory addresses).