AND函数序言中的操作

时间:2014-08-12 05:40:11

标签: assembly

我只是围绕着功能序言的概念,但这给了我一些麻烦。

我在C中编写了一个简单的hello world程序,然后查看了生成的汇编代码:

#include <stdio.h>

int main()
{
    puts("hello");
    return 0;
}

程序集(MinGW 4.8.1,Windows 7 32位):

004016B0   /$  55                         PUSH EBP
004016B1   |.  89E5                       MOV EBP,ESP
004016B3   |.  83E4 F0                    AND ESP,FFFFFFF0
004016B6   |.  83EC 10                    SUB ESP,10
004016B9   |.  E8 A2050000                CALL hello.00401C60
004016BE   |.  C70424 64504000            MOV DWORD PTR SS:[ESP],hello.00405064           ; |ASCII "hello"
004016C5   |.  E8 9E1F0000                CALL <JMP.&msvcrt.puts>                         ; \puts
004016CA   |.  B8 00000000                MOV EAX,0
004016CF   |.  C9                         LEAVE
004016D0   \.  C3                         RETN

ANDing ESP在第三行的目的是什么?我遇到过这个问题:Why does this function prologue use several instructions to calculate the esp reduction?,在哪里 据说

  

先清除esp中的低4位,新的esp将是   根据ABI,十六字节对齐。为什么不在main + 6之后简单地使用esp?   因为在x86上,堆栈从内存顶部向下增长。   简单地掩盖esp的低位可能会破坏当地的情况   变量。因此减法使堆栈增长到16   字节边界。

所以我的问题是,为什么要这样做?它在性能方面是否更好,或者编译器只是遵循一些固定标准?

1 个答案:

答案 0 :(得分:1)

将堆栈对齐在16字节边界上。对齐堆栈的原因是需要16字节对齐的东西,如16字节SSE向量,可以用作函数中的局部变量。

我应该补充一点,这通常只由MinGW为main完成。它在程序开始时将堆栈对齐一次,然后通过始终将堆栈增加16个字节的倍数,使堆栈在其他函数中保持16字节对齐。