views:

85

answers:

3

as a beginner of asm, I am checking gcc -S generated asm code to learn.

why gcc 4.x default reserve 8 bytes for stack when calling a method?

func18 is the empty function with no return no param no local var defined. I can't figure out why 8 bytes is reserved here (neither any forum/site mention for the reason, ppl seems take it for granted) is it for the %ebp just push? or return type?! many thx!

      .globl _func18
  _func18:
     pushl   %ebp 
     movl    %esp, %ebp 
     subl    $8, %esp 
     .text 
A: 

As richard mentioned above, it's all because of optimization, showing below. but still I got no idea why 8 bytes reserved is something optimized?!

original c

void func18() {}
int main() {return 0;}

compile without optimization flag specified

    .text                                                                                   
.globl _func18
_func18:
    pushl   %ebp
    movl    %esp, %ebp
    subl    $8, %esp
    leave
    ret
.globl _main
_main:                                                                                      
    pushl   %ebp
    movl    %esp, %ebp
    subl    $8, %esp
    movl    $0, %eax
    leave
    ret
    .subsections_via_symbols

with -Os optimization flag, no more stack reserve

    .text
.globl _func18
_func18:
    pushl   %ebp
    movl    %esp, %ebp
    leave
    ret
.globl _main
_main:
    pushl   %ebp
    xorl    %eax, %eax
    movl    %esp, %ebp
    leave
    ret
    .subsections_via_symbols
nikcname
put this in your question, not in a separate answer
orlandu63
A: 

Easy way to find out: Have you empty function call another function with one parameter. If the parameter is stored directly to the stack (no push), then that's what the extra space is for.

Richard Pennington
I tried before, it seems not relate with it
nikcname
+6  A: 

Some instructions require certain data types to be aligned to as much as a 16-byte boundary (in particular, the SSE data type __m128). To meet this requirement, gcc ensures that the stack is initially 16-byte aligned, and allocates stack space in multiples of 16 bytes. If only a 4-byte return address and 4-byte frame pointer need to be pushed, 8 additional bytes are needed to keep the stack aligned to a 16-byte boundary. However, if gcc determines that the additional alignment is unnecessary (i.e. the fancy data types are not used and no external functions are called), then it may omit any additional instructions used to align the stack. The analysis necessary to determine this may require certain optimization passes to be performed.

See also the gcc documentation for the option -mpreferred-stack-boundary=num.

mark4o
thx mark, so it's all for data alignement when optimizing with sse, very sensible as I disable the optimization and the subl $8 %esp is gone. the gcc ref is very useful!!! just 1 thing, while I adj the -mpreferred-stack-boundary, the reservation only chg between 3 and 4, from 4 to 12, it sticks with 8 bytes, I thought the reservation should then be 20 bytes, no?
nikcname
If you used -mpreferred-stack-boundary=12, then in any function that calls external functions it will allocate stack space in multiples of 2^12=4096 bytes. If you are not calling any external functions then it will often be able to figure out that maintaining that alignment isn't needed for the code it is generating (depends on your exact gcc version, options, and target architecture).
mark4o
so you mean in the case func without calling external func, gcc just stick with 8 bytes whatsoever as default?
nikcname
@nikcname: I don't see that on gcc 4.4.1 (Ubuntu 9.10) with an empty function. What version and compile options are you using?
mark4o