New to assembly. I have the following function
int foo(char *argv[])
{
char buf[256];
bar(argv[1], buf);
}
Which in assembly is --
0x08048473 <foo+0>:push %ebp
0x08048474 <foo+1>:mov %esp,%ebp
0x08048476 <foo+3>:sub $0x118,%esp
0x0804847c <foo+9>:mov 0x8(%ebp),%eax
0x0804847f <foo+12>:add $0x4,%eax
0x08048482 <foo+15>:mov (%eax),%edx
0x08048484 <foo+17>:lea -0x100(%ebp),%eax
0x0804848a <foo+23>:mov %eax,0x4(%esp)
0x0804848e <foo+27>:mov %edx,(%esp)
0x08048491 <foo+30>:call 0x8048454 <bar>
0x08048496 <foo+35>:leave
0x08048497 <foo+36>:ret
Can someone explain this to me please? Why is there a sub 280 there? 开发者_运维知识库The 256 bytes are allocated on the stack sure. I cannot explain the rest.
The stack is used for the local variables but also for intermediate values that the function need. Here, your foo()
function calls bar()
by giving it two pointers, one to the string (argv[1]
) and the other to the buf
variable; those pointer values are pushed on the stack, namely in the mov %eax,0x4(%esp)
and mov %edx,(%esp)
opcodes. Thus, foo()
needs a bit more than 256 bytes of stack space.
In more details:
0x08048473 <foo+0>:push %ebp
0x08048474 <foo+1>:mov %esp,%ebp
That's the standard function prologue: the function will use %ebp
to points to the stack elements before it was called (i.e. its arguments).
0x08048476 <foo+3>:sub $0x118,%esp
Some space is reserved on the stack, mainly (but not only) for buf[]
.
0x0804847c <foo+9>:mov 0x8(%ebp),%eax
0x0804847f <foo+12>:add $0x4,%eax
0x08048482 <foo+15>:mov (%eax),%edx
0x8(%ebp)
is the argv
function argument; these opcodes fetch the pointer from argv[1]
and store the result in %edx
. This will become the first argument to bar()
.
0x08048484 <foo+17>:lea -0x100(%ebp),%eax
This stores in %eax
the address of buf[]
-- the compiler decided that buf[]
was to be located in the upper 256 bytes of the stack space it reserved with sub
.
0x0804848a <foo+23>:mov %eax,0x4(%esp)
0x0804848e <foo+27>:mov %edx,(%esp)
The two arguments for bar()
are pushed on the stack (actually, written in the two top stack positions, %esp
having been already adjusted).
0x08048491 <foo+30>:call 0x8048454 <bar>
bar()
is called.
0x08048496 <foo+35>:leave
0x08048497 <foo+36>:ret
leave
undoes the prologue (it is equivalent to mov %ebp, %esp; pop %ebp
). ret
exits the function.
GCC is known to overallocate a bit on the stack; here, it could have reserved 264 bytes instead of 280. This seems to be an artefact of its internal register allocation optimizer (the extra stack slots were used to store intermediate values, but the optimizer finally found ways to keep the corresponding values in registers only).
精彩评论