0

In order to continue this: Debugging C program (int declaration) I decided to test more code and see how compiler reacts to it. So I decided to try this one to test local variables:

#include <stdio.h>
main()
{
  int a,b,c,d,e,f,g;
  a=0xbeef;
  b=0xdead;
  c=0x12;
  d=0x65;
  e=0xfed;
  f=0xaa;
  g=0xfaceb00c;
  a=a+b;
  printf("%d",a);
}

Ok I did that int a,b,c... just to test the main's frame size and see the sub $0x10,%esp growing up, (I'm under linux so that is why maybe is sub), now to sub $0x30,%esp so here is the the gdb output with "disas main" command:

   0x0804841c <+0>:  push   %ebp
   0x0804841d <+1>:  mov    %esp,%ebp
   0x0804841f <+3>:  and    $0xfffffff0,%esp
   0x08048422 <+6>:  sub    $0x30,%esp ;7 int vars 4-byte is 7*4=28. 30 is enough
   0x08048425 <+9>:  movl   $0xbeef,0x14(%esp)
   0x0804842d <+17>: movl   $0xdead,0x18(%esp)
   0x08048435 <+25>: movl   $0x12,0x1c(%esp)
   0x0804843d <+33>: movl   $0x65,0x20(%esp)
   0x08048445 <+41>: movl   $0xfed,0x24(%esp)
   0x0804844d <+49>: movl   $0xaa,0x28(%esp)
   0x08048455 <+57>: movl   $0xfaceb00c,0x2c(%esp)
   0x0804845d <+65>: mov    0x18(%esp),%eax
   0x08048461 <+69>: add    %eax,0x14(%esp)
   0x08048465 <+73>: mov    0x14(%esp),%eax
   0x08048469 <+77>: mov    %eax,0x4(%esp)
   0x0804846d <+81>: movl   $0x8048510,(%esp)
   0x08048474 <+88>: call   0x80482f0 <printf@plt>
   0x08048479 <+93>: leave  
   0x0804847a <+94>: ret    

This line: 0x0804841f <+3>:and $0xfffffff0,%esp what is and operator and why is there a large number?

And why the offset in movl commands isn't negative like: movl $0xa,-0x4(%ebp) So far I know is the AND is a logical operator like 1 and 1 is 1, 0 and 0 is 0, 1 and 0 is 0 etc... If it is the case, %esp has the ebp value that was the base frame address of who called the main function.

can any of you explain why this is compiled like this?

I think I'm missing something. Edit: I saw some "topics" on stackoverflow talking about this. Going to share: link1 link2 link3

Community
  • 1
  • 1
int3
  • 658
  • 1
  • 5
  • 21
  • 1
    `and $0xfffffff0,%esp` is used to clear the lower 4 bits of `%esp`; i.e. to align it on a 16-byte boundary. – Michael Oct 06 '13 at 21:12
  • hum gdb: `1: $esp = (void *) 0xbffff6f0 ; this is on +9 offset to main.` so is this moving to `movl $0xbeef,0x14(%esp)` – int3 Oct 06 '13 at 21:18
  • I found this: [link](http://stackoverflow.com/questions/4228261/understanding-the-purpose-of-some-assembly-statements) – int3 Oct 06 '13 at 21:19
  • "7 int vars 4-byte is 7*4=28. 30 is enough" -- your comment? The '30' is in *hex*, so it's **48** bytes. (Rest assured, it's still "enough".) – Jongware Oct 06 '13 at 22:15
  • @Jongware yup you are right – int3 Oct 06 '13 at 22:28

1 Answers1

0
  • Why is the offset in movl $0xbeef,0x14(%esp) not negative?

Because unlike in the other example, addressing is relative to esp, not ebp. esp is on one end of the stack, esp on the other one. So in order to get an address inside the current stack frame, you need to add to esp or subtract from ebp.

  • Why and $0xfffffff0,%esp?

For alignment. @BlackBear explains this in the answer to your previous question: Debugging C program (int declaration)

Community
  • 1
  • 1
us2012
  • 16,083
  • 3
  • 46
  • 62
  • so CPU run 128bit of data (16bytes) at same time? if this is not aligned in memory it could read half of commands like for example: `xor %eax,%eax` is aligned and not align is: `r %eax,%eaxle` that %eaxle the "le" is the next command to run because of that " bad alignment" right? Am I correct? – int3 Oct 06 '13 at 21:36
  • @int3 No, that sounds very confused and is not at all what this is about. The reason is *data* alignment, for example when you have a function parameter that is a packed 128bit SSE vector. For performance reasons, such a vector has to start at an address which is divisible by 16. – us2012 Oct 06 '13 at 21:37
  • I'm a bit confuse. So in other words it is not possible to push 3bytes of data right? it must be always 2,4,8,.. byte long? If there is something on memory that has 3byte or 5byte long there must have somekind of commands to align the stack?. – int3 Oct 06 '13 at 22:42
  • I'm really not sure what you mean. The instruction `push` does not come in a flavour that would allow pushing a block of 3 bytes, but you can still `mov` them individually, of course. – us2012 Oct 06 '13 at 22:53
  • so if I use mov's and make the stack unaligned means the cpu must to realign that again in order to not lose any data of the frame? – int3 Oct 06 '13 at 23:03
  • You don't make the stack unaligned by moving data to a stack address. – us2012 Oct 06 '13 at 23:12
  • I found a better explanation here: [http://stackoverflow.com/questions/4175281/what-does-it-mean-to-align-the-stack](http://stackoverflow.com/questions/4175281/what-does-it-mean-to-align-the-stack) :) – int3 Oct 07 '13 at 09:57