问题
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.
回答1:
Two things:
- 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.
- 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.
回答2:
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.
回答3:
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)
来源:https://stackoverflow.com/questions/20865235/why-gcc-disassembler-allocating-extra-space-for-local-variable