简体   繁体   中英

Can't set stack boundary gcc

My c code:

#include <stdio.h>

foo()
{
  char buffer[8];
}

main()
{
  foo();
  return 0;
}

I compile it using gcc -ggdb -mpreferred-stack-boundary=2 -o bar bar.c

When I load it using GDB ./bar I see that inside the foo function the code is:

sub $0x0c,$esp

Why is this happening?

I want to buffer to take 8 bytes in the stack so it should be sub $0x8,$esp !

Why can't I set stack boundary to 4 bytes?

Help!

I can't reproduce exactly what you are seeing, but on my 4.8.2 version of gcc, the option does affect the amount of stack used with this code (make sure "buffer" is used to avoid it being optimised away, and fix the warnings for no return type/argument types):

#include <stdio.h>

void foo(void)
{
    char buffer[8];
    buffer[0] = 'a';
    buffer[1] = '\n';
    buffer[2] = 0;
    printf("my first program! %s\n", buffer);
}

int main()
{
    foo();
    return 0;
}

Compiled with -mpreferred-stack-boundary=2 and -mpreferred-stack-boundary=4, and the difference between the generated assembler is notable:

$ diff -u stb-2.s stb-4.s 
--- stb-2.s 2014-04-10 09:00:39.546038191 +0100
+++ stb-4.s 2014-04-10 09:00:58.895108979 +0100
@@ -15,11 +15,11 @@
    .cfi_offset 5, -8
    movl    %esp, %ebp
    .cfi_def_cfa_register 5
-   subl    $16, %esp
-   movb    $97, -8(%ebp)
-   movb    $10, -7(%ebp)
-   movb    $0, -6(%ebp)
-   leal    -8(%ebp), %eax
+   subl    $40, %esp
+   movb    $97, -16(%ebp)
+   movb    $10, -15(%ebp)
+   movb    $0, -14(%ebp)
+   leal    -16(%ebp), %eax
    movl    %eax, 4(%esp)
    movl    $.LC0, (%esp)
 .LEHB0:
@@ -67,9 +67,10 @@
    .cfi_offset 5, -8
    movl    %esp, %ebp
    .cfi_def_cfa_register 5
+   andl    $-16, %esp
    call    _Z3foov
    movl    $0, %eax
-   popl    %ebp
+   leave
    .cfi_restore 5
    .cfi_def_cfa 4, 4
    ret

So, at least in gcc 4.8.2. for x86-32, the option has an effect.

Of course, the default according to the docs is -mpreferred-stack-boundary=2, so maybe that's why you can't see any difference from "without" (Although in my experiments, it seems that it's -mpreferred-stack-boundary=4). [Moment passes] Ah, the default has been changed over time, so the 4.4.2 docs online says 2, my info gcc for 4.8.2 says 4, which explains the difference.

As to why your code is allocating twelve bytes of stack-space - look at how printf is called:

movl    $.LC0, (%esp)
call    printf

If the compiler can, it will pre-allocate argument space for function calls at the start of the function, rather than use push $.LC0 as it would be in this case. It's not much difference, but it saves at least one instruction for cleanup at the other side of printf (and it makes it MUCH easier to deal with stack-relative offsets within the produced code, since the compiler doesn't have to keep track of where the current stack-pointer is - it's always at a constant place after the prologue code at the beginning of the function, all the way to the end of the function). Since the space is ultimately required anyway, there's no point in "saving 4 bytes".

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM