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();
}
Here is the disassembly code by gdb 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, buffer is allocated for 0x10(16) bytes, but in func_2 , it is allocated for 0x18(24) bytes, why?
Edit: @Attie figure out that buffer size is actually the same for both, but there's strange 8-byte stack spaces in func_2 don't know where it comes from.
I have just tried to reproduce this, see below:
Compiling for x86-64 (no joy):
$ 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
Compiling for i386 (success):
$ 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
This doesn't appear to be related to any of the following:
getchar() is a library function, and thus we are calling into the PLT (Procedure Linkage Table).main()
If you however increase the size of your buffer by one, to 17, then the stack usage increases to 32 and 40 bytes (from 16 and 24 bytes) respectively. The difference is 16 bytes, which is used for alignment, as answered here.
I can't answer why the stack alignment appears to be off by 8-bytes upon entering func_2() though.
If you update func_1() and func_2() to have a 15-byte buffer, and a single byte variable, and write data to them, then you can see where these items are in the stack frame:
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With