在汇编时Int与Double

时间:2016-12-14 11:56:13

标签: c++ c gcc x86 reverse-engineering

为什么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);

你能解释为什么会发生这种情况,为什么不总是这样?

1 个答案:

答案 0 :(得分:7)

对于自动作用域中的double(在堆栈上),额外的代码将堆栈帧与偶数8字节边界对齐,以便double变量存储在内存中具有适当对齐的地址。进入函数时,堆栈指针不能保证在一个偶数8字节的边界上对齐,编译器会添加额外的代码来实现它。

这就是and esp, -8的作用。 -8是0xFFFFFFF8。这将使用esp清除and的最后3位,使其指向偶数8字节的边界内存地址,将其调低(堆栈从高内存地址增长到低内存地址)。