example3.c:
------------------------------------------------------------------------------
void function(int a, int b, int c) {
char buffer1[5]; // 8 byte im stack (DW)
char buffer2[10]; // 12 byte im stack
int *ret;
ret = buffer1 + 12; // ende von buffer1 + 4 byte FP
(*ret) += 8; // return-adresse um 8 erhöhen
}
void main() {
int x;
x = 0;
function(1,2,3);
x = 1; // diese anweisung überspringen (8 byte)
printf("%d\n",x);
}
------------------------------------------------------------------------------
dies sollte rauskommen: (gdb-output)
------------------------------------------------------------------------------
Dump of assembler code for function main:
0x8000490 <main>: pushl %ebp ; ebp retten,
0x8000491 <main+1>: movl %esp,%ebp
0x8000493 <main+3>: subl $0x4,%esp ; 4 byte stack?
0x8000496 <main+6>: movl $0x0,0xfffffffc(%ebp) ; was bedeutet das? scheiß at&t-syntax
0x800049d <main+13>: pushl $0x3 ; params pushen
0x800049f <main+15>: pushl $0x2
0x80004a1 <main+17>: pushl $0x1
0x80004a3 <main+19>: call 0x8000470 <function>
0x80004a8 <main+24>: addl $0xc,%esp ; 12 zu esp addieren? sind das die 3 params? (3 * DW)
0x80004ab <main+27>: movl $0x1,0xfffffffc(%ebp) ; ist das x = 1? was ist denn bitteschön 0xfffffffc(%ebp)??
0x80004b2 <main+34>: movl 0xfffffffc(%ebp),%eax ; x als param nach eax,
0x80004b5 <main+37>: pushl %eax ; param für printf pushen
0x80004b6 <main+38>: pushl $0x80004f8 ; was ist das?
0x80004bb <main+43>: call 0x8000378 <printf>
0x80004c0 <main+48>: addl $0x8,%esp ; aufräumarbeiten?
0x80004c3 <main+51>: movl %ebp,%esp
0x80004c5 <main+53>: popl %ebp
0x80004c6 <main+54>: ret
0x80004c7 <main+55>: nop
----------------------------------------------------------------
und jetzt mein ergebnis, das der gcc gebaut hat. (gdb-output again)
-----------------------------------------------------------------
Dump of assembler code for function main:
0x0804840e <main+0>: lea 0x4(%esp),%ecx ; was
0x08048412 <main+4>: and $0xfffffff0,%esp ; ist
0x08048415 <main+7>: pushl 0xfffffffc(%ecx) ; das???
0x08048418 <main+10>: push %ebp ; bp retten, usw
0x08048419 <main+11>: mov %esp,%ebp
0x0804841b <main+13>: push %ecx
0x0804841c <main+14>: sub $0x24,%esp ; oh, krieg ich 24byte stack?
0x0804841f <main+17>: movl $0x0,0xfffffff8(%ebp) ; x = 0; trotzdem krieg ich dieses 0xfffffff8(%ebp) nicht gelesen
0x08048426 <main+24>: movl $0x3,0x8(%esp) ; parameter übergeben. pushl ist anscheinend out :(
0x0804842e <main+32>: movl $0x2,0x4(%esp) ; kann doch kein mensch lesen
0x08048436 <main+40>: movl $0x1,(%esp)
0x0804843d <main+47>: call 0x80483d4 <function>
0x08048442 <main+52>: movl $0x1,0xfffffff8(%ebp) ; x = 1;
0x08048449 <main+59>: mov 0xfffffff8(%ebp),%eax ; x nach eax
0x0804844c <main+62>: mov %eax,0x4(%esp) ; eax auf den stack
0x08048450 <main+66>: movl $0x804853c,(%esp) ; was auch immer das ist? ret-adresse? müsste das nicht 0x0804845c sein?
0x08048457 <main+73>: call 0x8048308 <printf@plt>
0x0804845c <main+78>: add $0x24,%esp ; was auch immer jetzt wieder kommt?
0x0804845f <main+81>: pop %ecx
0x08048460 <main+82>: pop %ebp
0x08048461 <main+83>: lea 0xfffffffc(%ecx),%esp
0x08048464 <main+86>: ret
End of assembler dump.