If I have the following code:

struct bob{
        int a;
        char b[8];
        int c;
};
struct bob barker;
...
void sub1(unsigned int size){
        int someflag=0;
        struct bob dole;
        memcpy(&dole.b,&barker.b,size);
}

let's say I call the code as sub(8) (the code is intentionally written
to allow overflows).

and I compile it with just plain "gcc -o test test.c", I get the
following assembly

08048427 <sub1>:
 8048427:       55                      push   %ebp
 8048428:       89 e5                   mov    %esp,%ebp
 804842a:       57                      push   %edi
 804842b:       56                      push   %esi
 804842c:       83 ec 20                sub    $0x20,%esp
 804842f:       c7 45 f4 00 00 00 00    movl   $0x0,0xfffffff4(%ebp)
 8048436:       8d 45 e4                lea    0xffffffe4(%ebp),%eax
 8048439:       83 c0 04                add    $0x4,%eax
 804843c:       8b 55 08                mov    0x8(%ebp),%edx
 804843f:       89 c7                   mov    %eax,%edi
 8048441:       be ac 96 04 08          mov    $0x80496ac,%esi
 8048446:       fc                      cld
 8048447:       89 d1                   mov    %edx,%ecx
 8048449:       f3 a4                   rep movsb %ds:(%esi),%es:(%edi)
 804844b:       83 c4 20                add    $0x20,%esp
 804844e:       5e                      pop    %esi
 804844f:       5f                      pop    %edi
 8048450:       5d                      pop    %ebp
 8048451:       c3                      ret

Now, the weird thing about this assembly to me, is that when I track
the usage of the stack, I can't help but notice that it seems like
about 3 words (0xC bytes) too many seem to get allocated with that sub
$0x20 instruction. That is to say, I have the someflag local variable,
which should take up 0x4 + the bob dole struct which is 0x10 = 0x14
bytes required for local variables. Further, we can see that the while
the address %ebp - 0x1C (start of dole) gets accessed, but %ebp -
0x20, 0x24, 0x28 also get allocated by that initial sub, but never get
touched.

I noticed also that when I replace the memcpy with a strcpy for
instance, while gdb will allocate space for the parameters to be
passed to strcpy, they're esp-relative accesses, rather than the
ebp-relative that one normally sees for local variables, BUT there is
still 3 extra words of data between the beginning of dole, and the
beginning of the stack parameters...so again, they never get touched!

(08048450 <sub1>:
 8048450:       55                      push   %ebp
 8048451:       89 e5                   mov    %esp,%ebp
 8048453:       83 ec 28                sub    $0x28,%esp
 8048456:       c7 45 fc 00 00 00 00    movl   $0x0,0xfffffffc(%ebp)
 804845d:       c7 44 24 04 d0 96 04    movl   $0x80496d0,0x4(%esp)
 8048464:       08
 8048465:       8d 45 ec                lea    0xffffffec(%ebp),%eax
 8048468:       83 c0 04                add    $0x4,%eax
 804846b:       89 04 24                mov    %eax,(%esp)
 804846e:       e8 95 fe ff ff          call   8048308 <[EMAIL PROTECTED]>
 8048473:       c9                      leave
 8048474:       c3                      ret)

Basically I'm just curious to understand why gcc adds this extra space.

Thanks

Gary Guy

Reply via email to