Gcc 堆栈框架是否对齐到不同的大小?

Gcc 堆栈框架是否对齐到不同的大小?,gcc,stack,frame,Gcc,Stack,Frame,这是一个简单的测试。在中讨论了类似的主题,但当我编译以下两个源代码时,我得到了相互矛盾的结果 #include <stdio.h> //first source code void haha() { printf("HI"); } int main() { int b = 2; b = b << 1; haha(); //printf("n

这是一个简单的测试。在中讨论了类似的主题,但当我编译以下两个源代码时,我得到了相互矛盾的结果

 #include <stdio.h>
 //first source code
    void haha()
    {
      printf("HI");
    }
    int main()
    {
      int b = 2;
      b = b << 1;
      haha();
      //printf("n = %d",b);
      return 0;
    }
对于第二个源代码,我得到了汇编代码:

haha:
    pushl   %ebp
    movl    %esp, %ebp
    subl    $24, %esp
    movl    $.LC0, %eax
    movl    %eax, (%esp)
    call    printf
    leave
    ret
    .size   haha, .-haha
.globl main
    .type   main, @function
main:
    pushl   %ebp
    movl    %esp, %ebp
    andl    $-16, %esp
    subl    $16, %esp
    movl    $2, 12(%esp)
    sall    12(%esp)
    call    haha
    movl    $0, %eax
    leave
    ret
haha3:
    pushl   %ebp
    movl    %esp, %ebp
    subl    $16, %esp
    movl    -4(%ebp), %eax
    movl    -8(%ebp), %edx
    leal    (%edx,%eax), %eax
    movl    %eax, -12(%ebp)
    leave
    ret
    .size   haha3, .-haha3
.globl haha2
    .type   haha2, @function
haha2:
    pushl   %ebp
    movl    %esp, %ebp
    subl    $16, %esp
    movl    -4(%ebp), %eax
    movl    -8(%ebp), %edx
    leal    (%edx,%eax), %eax
    movl    %eax, -12(%ebp)
    call    haha3
    leave
    ret
    .size   haha2, .-haha2
.globl main
    .type   main, @function
main:
    pushl   %ebp
    movl    %esp, %ebp
    subl    $16, %esp
    movl    $2, -4(%ebp)
    sall    -4(%ebp)
    call    haha2
    movl    $0, %eax
    leave
    ret
我的问题是为什么第一个代码的堆栈帧与24(subl$24,%esp)对齐,第二个与16(subl$16,%esp)对齐?
据说SSEx指令系列要求压缩128位向量与16字节对齐。因此,我希望第一个代码的堆栈帧有subl$32、%esp和subl$16、%esp用于第二个代码,或者subl$24、%esp用于第一个代码,subl$8、%esp用于第二个代码,因为如前所述,leave和ret保留了8个字节。但是,事实上,第一个代码使用'subl$24,%esp',第二个代码使用'subl$16,%esp',感谢您的关注。

如果在第二个示例中有额外的局部变量,为什么您希望堆栈帧具有相同的大小?这在堆栈分配、填充和对齐()中有说明SSEx指令系列要求压缩128位向量与16字节对齐。因此,我希望第一个代码的堆栈帧有一个
subl$32、%esp
subl$16、%esp
用于第二个代码,或者
subl$24、%esp
用于第一个代码,而
subl$8、%esp
用于第二个代码,因为前面提到的leave和ret保留了8个字节。但是,事实上,第一个代码使用“subl$24,%esp”,第二个代码使用“subl$16,%esp”。如何解释这个结果?谢谢:)
haha3:
    pushl   %ebp
    movl    %esp, %ebp
    subl    $16, %esp
    movl    -4(%ebp), %eax
    movl    -8(%ebp), %edx
    leal    (%edx,%eax), %eax
    movl    %eax, -12(%ebp)
    leave
    ret
    .size   haha3, .-haha3
.globl haha2
    .type   haha2, @function
haha2:
    pushl   %ebp
    movl    %esp, %ebp
    subl    $16, %esp
    movl    -4(%ebp), %eax
    movl    -8(%ebp), %edx
    leal    (%edx,%eax), %eax
    movl    %eax, -12(%ebp)
    call    haha3
    leave
    ret
    .size   haha2, .-haha2
.globl main
    .type   main, @function
main:
    pushl   %ebp
    movl    %esp, %ebp
    subl    $16, %esp
    movl    $2, -4(%ebp)
    sall    -4(%ebp)
    call    haha2
    movl    $0, %eax
    leave
    ret