3

Here is a simple program in C for which I used gdb to disassemble it to understand what is happening.

#include <stdio.h>
#include <string.h>
int main(){
    printf("%d", sizeof(foo("HELLOWORLD")));
}

int foo(char* c)
{
   printf("%s\n",c);
}

And below is the corresponding assembly code for disassemble main

0x08048414 <+0>:    push   %ebp
   0x08048415 <+1>: mov    %esp,%ebp
   0x08048417 <+3>: and    $0xfffffff0,%esp
   0x0804841a <+6>: sub    $0x10,%esp
   0x0804841d <+9>: mov    $0x8048520,%eax
   0x08048422 <+14>:    movl   $0x4,0x4(%esp)
   0x0804842a <+22>:    mov    %eax,(%esp)
   0x0804842d <+25>:    call   0x8048320 <printf@plt>
   0x08048432 <+30>:    leave  
   0x08048433 <+31>:    ret   

And below is disassemble foo

0x08048434 <+0>:    push   %ebp
   0x08048435 <+1>: mov    %esp,%ebp
   0x08048437 <+3>: sub    $0x18,%esp
   0x0804843a <+6>: mov    0x8(%ebp),%eax
   0x0804843d <+9>: mov    %eax,(%esp)
   0x08048440 <+12>:    call   0x8048330 <puts@plt>
   0x08048445 <+17>:    leave  
   0x08048446 <+18>:    ret  

I m confused about these instructions:

  1. 0x08048417 <+3> and $0xfffffff0,%esp Why stack pointer needs to be aligned when it is not modified before?

  2. 0x0804841a <+6>:sub $0x10,%esp what exactly is this instruction doing particular to the program?

  3. 0x0804841d <+9>:mov $0x8048520,%eax what is this instruction doing particular to the program?

  4. mov %eax,(%esp) What does parenthesis around %esp mean?

Would be helpful if someone explained this.

nrz
  • 10,435
  • 4
  • 39
  • 71
Vindhya G
  • 1,339
  • 2
  • 21
  • 46

1 Answers1

2
  1. belongs to the (function-)prologue, it is aligning the SP to a 16-byte boundary, by bitmasking the SP.

  2. memory for the stack-frame is created, as your pointer needs to be passed to the function. The address will be passed from the stack to the function. Yet it seems that the expression is evluated at compile-time, so no need for the actual call.

  3. 0x8048520 is probably the adress of your string "%d". It is being put into eax, from there on it is put on the stack using the stackpointer.

There is plenty of material around, like this.

unwind
  • 391,730
  • 64
  • 469
  • 606
bash.d
  • 13,029
  • 3
  • 29
  • 42
  • but as the function foo is not called(there is no call instruction in main)why Hello world is added to stack..and is it necessary to align SP everytime new function is called? – Vindhya G Feb 28 '13 at 13:39
  • @bash.d: It is not the address of "HELLOWORLD", but most likely the address of the printf format string. `foo` is not called at all since the whole `sizeof` operator is evaluated at compile-time to `4`. – Blagovest Buyukliev Feb 28 '13 at 13:39
  • address of printf is 0x0804832b – Vindhya G Feb 28 '13 at 13:40
  • 2
    @vindhya: The `and` operation with the stack pointer "rounds it down" to the closest 16-byte boundary. Putting data at such boundaries enables the computer to fetch and process that data more efficiently. – Blagovest Buyukliev Feb 28 '13 at 13:49
  • Not all of the 16bytes are actually used. The stack is used to pass arguments from one function to another. The calling function assigns space on the stack (creating a stack-frame) and the callee (the function that is called), can access the arguments from the stack. – bash.d Feb 28 '13 at 13:50
  • @ Blagovest Buyukliev:thanks.COuld you please clarify one more thing i could not understand..what does 0x8048520 has? – Vindhya G Feb 28 '13 at 13:52
  • @vindhya: it is the address of the string `"%d"`. – Blagovest Buyukliev Feb 28 '13 at 13:55
  • @bash.d:And one more thing. could you please explain why value from %eax is moved to space pointed to %esp? – Vindhya G Feb 28 '13 at 13:55
  • @vindhya This what you could call "putting it on the stack". As the stack is a contiguous area of memory you can't put anything "on" it literally, but this is how it works. – bash.d Feb 28 '13 at 13:56
  • @bash.d:so do you mean address 0x8048520 cannot be added directly to %esp as in mov $0x8048520,(%esp) ? – Vindhya G Feb 28 '13 at 13:58
  • This depends on the OS, I guess. Some OS's use the registers (eax, ebx, ecx, edx) to pass arguments. But this would require the registers to be saved first using push-instructions. Using SP is more "convenient" and allows (technically) many, many arguments to be passed. – bash.d Feb 28 '13 at 14:01
  • @bash.d:why cant address 0x8048520 cannot be added directly to %esp as in mov $0x8048520? – Vindhya G Feb 28 '13 at 14:03
  • @vindhya: I suppose the compiler wants to "at least leave something" in `eax` since you do not have a `return` statement and the function returns `int`. Normally the `eax` register would be used for the return value, but in this case it is absent. – Blagovest Buyukliev Feb 28 '13 at 14:08
  • @ Blagovest Buyukliev:ok..thanks for your insight..but just for confirmation we can use mov $0x8048520,(%esp) right? – Vindhya G Feb 28 '13 at 14:11
  • @vindhya: Yes, a "smarter" compiler would do that. – Blagovest Buyukliev Feb 28 '13 at 14:13