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