Why does gcc sometimes allocate extra space for local, but sometimes not?

Here is my code

#include <stdio.h>                                                              

char func_with_ret()
{
    return 1;
}
void func_1()
{
    char buf[16];
    func_with_ret();
}
void func_2()
{
    char buf[16];
    getchar();
}
int main()
{
    func_1();
    func_2();
}
  • I declare 16 byte local buffers to align the stack pointer (for x86).
  • I write two functions func_1, func_2, they look almost the same - allocate a 16-byte local buffer and call the function with a char return value and no parameter, but one is self-defined and the other is getchar ().
  • Compile with the gcc parameter "-fno-stack-protector" (so there is no canary on the stack) and "-O0" to avoid unexpected optimization behavior.

Here is the gdb disassembly code for func_1 and func_2.

Dump of assembler code for function func_1:
   0x08048427 <+0>:     push   ebp
   0x08048428 <+1>:     mov    ebp,esp
   0x0804842a <+3>:     sub    esp,0x10
   0x0804842d <+6>:     call   0x804841d <func_with_ret>
   0x08048432 <+11>:    leave  
   0x08048433 <+12>:    ret 

Dump of assembler code for function func_2:
   0x08048434 <+0>:     push   ebp
   0x08048435 <+1>:     mov    ebp,esp
   0x08048437 <+3>:     sub    esp,0x18
   0x0804843a <+6>:     call   0x80482f0 <getchar@plt>
   0x0804843f <+11>:    leave  
   0x08048440 <+12>:    ret

In func_1, the buffer is allocated for 0x10 (16) bytes, but in func_2 it is allocated for 0x18 (24) bytes, why?


: @Attie , , 8- func_2 , .

+6
1

, . :

x86-64 ( ):

$ gcc p.c -g -o p -O0 -fno-stack-protector
$ objdump -d p

p:     file format elf64-x86-64

[...]

0000000000400538 <func_1>:
  400538:       55                      push   %rbp
  400539:       48 89 e5                mov    %rsp,%rbp
  40053c:       48 83 ec 10             sub    $0x10,%rsp
  400540:       b8 00 00 00 00          mov    $0x0,%eax
  400545:       e8 e3 ff ff ff          callq  40052d <func_with_ret>
  40054a:       c9                      leaveq
  40054b:       c3                      retq

000000000040054c <func_2>:
  40054c:       55                      push   %rbp
  40054d:       48 89 e5                mov    %rsp,%rbp
  400550:       48 83 ec 10             sub    $0x10,%rsp
  400554:       e8 c7 fe ff ff          callq  400420 <getchar@plt>
  400559:       c9                      leaveq
  40055a:       c3                      retq

i386 ():

$ gcc p.c -g -o p -O0 -fno-stack-protector -m32
$ objdump -d p

p:     file format elf32-i386

[...]

08048427 <func_1>:
 8048427:       55                      push   %ebp
 8048428:       89 e5                   mov    %esp,%ebp
 804842a:       83 ec 10                sub    $0x10,%esp
 804842d:       e8 eb ff ff ff          call   804841d <func_with_ret>
 8048432:       c9                      leave
 8048433:       c3                      ret

08048434 <func_2>:
 8048434:       55                      push   %ebp
 8048435:       89 e5                   mov    %esp,%ebp
 8048437:       83 ec 18                sub    $0x18,%esp
 804843a:       e8 b1 fe ff ff          call   80482f0 <getchar@plt>
 804843f:       c9                      leave
 8048440:       c3                      ret

:

  • , getchar() , , , PLT ( ).
  • main()
  • /

, , , 17, 32 40 ( 16 24 ) . 16 , , .

, 8 func_2(), .


func_1() func_2(), 15- , , :

void func_1(void) {
    char buf[15];
    char x;
    buf[0] = 0xaa;
    x = 0x55;
    func_with_ret();
}

void func_2(void) {
    char buf[15];
    char x;
    buf[0] = 0xaa;
    x = 0x55;
    getchar();
}
08048434 <func_1>:
 8048434:       55                      push   %ebp
 8048435:       89 e5                   mov    %esp,%ebp
 8048437:       83 ec 10                sub    $0x10,%esp
 804843a:       c6 45 f0 aa             movb   $0xaa,-0x10(%ebp)
 804843e:       c6 45 ff 55             movb   $0x55,-0x1(%ebp)
 8048442:       e8 d6 ff ff ff          call   804841d <func_with_ret>
 8048447:       c9                      leave
 8048448:       c3                      ret

08048449 <func_2>:
 8048449:       55                      push   %ebp
 804844a:       89 e5                   mov    %esp,%ebp
 804844c:       83 ec 18                sub    $0x18,%esp
 804844f:       c6 45 e8 aa             movb   $0xaa,-0x18(%ebp)
 8048453:       c6 45 f7 55             movb   $0x55,-0x9(%ebp)
 8048457:       e8 94 fe ff ff          call   80482f0 <getchar@plt>
 804845c:       c9                      leave
 804845d:       c3                      ret
+1

Source: https://habr.com/ru/post/1016213/


All Articles