为什么GCC编译器在使用double时会添加这三行,而在有Int时不添加?
使用int:
#include <cstdio>
int main(){
int i = 1;
}
==&GT;
main:
push ebp
mov ebp, esp
sub esp, 16
mov DWORD PTR [ebp-4], 1
mov eax, 0
leave
ret
双击:
#include <cstdio>
int main(){
double i = 1;
}
==&GT;
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
使用指针时会发生类似情况,例如,int * s = new int(4);
你能解释为什么会发生这种情况,为什么不总是这样?
答案 0 :(得分:7)
对于自动作用域中的double
(在堆栈上),额外的代码将堆栈帧与偶数8字节边界对齐,以便double
变量存储在内存中具有适当对齐的地址。进入函数时,堆栈指针不能保证在一个偶数8字节的边界上对齐,编译器会添加额外的代码来实现它。
这就是and esp, -8
的作用。 -8是0xFFFFFFF8。这将使用esp
清除and
的最后3位,使其指向偶数8字节的边界内存地址,将其调低(堆栈从高内存地址增长到低内存地址)。