开发者

Can someone explain the assembly code please?

开发者 https://www.devze.com 2023-02-28 03:06 出处:网络
New to assembly. I have the following function int foo(char *argv[]) { char buf[256]; bar(argv[1], buf);

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).

0

精彩评论

暂无评论...
验证码 换一张
取 消