8

I have written simple function in C,

void GetInput()
{
    char buffer[8];
    gets(buffer);
    puts(buffer);
}

When I disassemble it in gdb's disassembler, it gives following disassembly.

   0x08048464 <+0>: push   %ebp
   0x08048465 <+1>: mov    %esp,%ebp
   0x08048467 <+3>: sub    $0x10,%esp
   0x0804846a <+6>: mov    %gs:0x14,%eax
   0x08048470 <+12>:    mov    %eax,-0x4(%ebp)
   0x08048473 <+15>:    xor    %eax,%eax
=> 0x08048475 <+17>:    lea    -0xc(%ebp),%eax
   0x08048478 <+20>:    mov    %eax,(%esp)
   0x0804847b <+23>:    call   0x8048360 <gets@plt>
   0x08048480 <+28>:    lea    -0xc(%ebp),%eax
   0x08048483 <+31>:    mov    %eax,(%esp)
   0x08048486 <+34>:    call   0x8048380 <puts@plt>
   0x0804848b <+39>:    mov    -0x4(%ebp),%eax
   0x0804848e <+42>:    xor    %gs:0x14,%eax
   0x08048495 <+49>:    je     0x804849c <GetInput+56>
   0x08048497 <+51>:    call   0x8048370 <__stack_chk_fail@plt>
   0x0804849c <+56>:    leave  
   0x0804849d <+57>:    ret    

Now please look at line number three, 0x08048467 <+3>: sub $0x10,%esp, I have only 8 bytes allocated as local variable, then why compiler is allocating 16 bytes(0x10).

Secondly, what is meaning of xor %gs:0x14,%eax.

@Edit: If it is optimization, is there any way to stop it.

Thanks.

Pranit Kothari
  • 9,721
  • 10
  • 61
  • 137
  • Possible duplicate of [Why does the compiler allocate more than needed in the stack?](http://stackoverflow.com/questions/37770751/why-does-the-compiler-allocate-more-than-needed-in-the-stack) – phuclv Dec 24 '16 at 17:13

3 Answers3

12

Two things:

  1. The compiler may reserve space for intermediate expressions to which you did not give names in the source code (or conversely not allocate space for local variables that can live entirely in registers). The list of stack slots in the binary does not have to match the list of local variables in the source code.
  2. On some platforms, the compiler has to keep the stack pointer aligned. For the particular example in your question, it is likely that the compiler is striving to keep the stack pointer aligned to a boundary of 16 bytes.

Regarding your other question that you should have asked separately, xor %gs:0x14,%eax is clearly part of a stack protection mechanism, enabled by default. If you are using GCC, turn it off with -fno-stack-protector.

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
Pascal Cuoq
  • 79,187
  • 7
  • 161
  • 281
  • I am learning Reverse Engineering, how I should understand this surprising behaviour? – Pranit Kothari Jan 01 '14 at 03:24
  • 3
    @pranitkothari There is nothing surprising about this. A modern compiler does not translate a program line by line. The goal of the compiler is to produce assembly code that is equivalent to the source code, even if it does everything differently or in a different order. Simply keep this in mind when you match assembly and source code. – Pascal Cuoq Jan 01 '14 at 03:27
5

Besides the other answers already given, gcc will prefer to keep the stack 16-byte aligned for storing SSE values on the stack since some (all?) of the SSE instructions require their memory argument to be 16-byte aligned.

Geoff Reedy
  • 34,891
  • 3
  • 56
  • 79
  • So that is the reason! I was wondering frequently about this, because gcc is doing this also on 32 bit systems, and I always thought maybe it is just some unimportant optimization for something else which they didn't bother with. – Devolus Jan 01 '14 at 09:03
4

This more builds upon Pascal's answer, but in this case, it's probably because of the stack protection mechanism.

You allocate 8 bytes, which is fair enough and taken into account with the stack pointer. In addition, the current stack protection address is saved to %ebp, which points to the top of the current stack frame on the following lines

0x0804846a <+6>: mov    %gs:0x14,%eax
0x08048470 <+12>:    mov    %eax,-0x4(%ebp)

This appears to take a four bytes. Given this, the other four bytes are probably for alignment of some form, or are taken up with some other stack information on the following lines:

=> 0x08048475 <+17>:    lea    -0xc(%ebp),%eax
   0x08048478 <+20>:    mov    %eax,(%esp)
slugonamission
  • 9,562
  • 1
  • 34
  • 41