> A function typically begins with code of the form:
>
> pushl %ebp
> movl %esp,%ebp
> subl $12,%esp
>
> and ends with:
>
> movl %ebp,%esp
> popl %ebp
> ret
hmm.,. I have written simple code which basically looks like:
#include <stdlib.h>
void main(int argc,char **argv,char **envp)
{ char s[1024];
strcpy(s,"some char data");
}
now I look in the source, generated with gcc -S somecode.c
pushl %ebp //
movl %esp,%ebp // so here we prepare the "procedure"
// so far I understood : passed data, previous ebp and return address for
// each produre, is called frame here, right?
subl $1024,%esp // reserve memory in stack for variables?
// (i added int foo; and got here subl $1028,%esp
// so, it reserves memory for all varibles
// altogether?
pushl $.LC0 // this label points to string.
// hmm, all arguments are passed to the calls
// in upside-down order, i.g first parameter is
// pushed last, right?
leal -1024(%ebp),%eax // -1024? it refers to local variable here?
//
pushl %eax // and why it pushes eax?
call strcpy
addl $8,%esp // and this thing is not clear to me..:(
// why would it want to incement stack?
.L1:
leave // this equal to
// movl %ebp,%esp
// popl %ebp
// right?
ret
> Upon entry to the function, the stack looks like this:
>
> param 3
> param 2
> param 1
> return address
> esp ->
hmm.. and what are there params? The parameters passed to procedure?
I played with gdb alittle, and found that main() has argc/ **argv
things.. so they are just pushl'ed into stack, just before main is called,
right?
> After the entry code has been executed, the stack looks like this:
> param 3
> param 2
> param 1
> return address
> saved ebp
/-> ebp -> local var 1
+----| > local var 2
| | > local var 3
| \-> esp ->..
|
+-- so this offset is done by sub-call. (which reserves mem). hmm.
compiler doesn't refer to variables by names at all here right? Does gcc
just "remembers" only offsets for each variable is stack?
> The exit code restores esp, undoing the effect of the `subl $12,%esp'
> (and any other stack adjustments which occur during the function), and
> then resores ebp to the value that it had upon entry.
Yeah. I see.
> Here, ebp is the `frame pointer'.
and the set of local variables, is frame. is it?
> The code which comprises the
> function refers to the function's parameters as ebp+<offset>, and
> local variables as ebp-<offset>.
so in the listing above, it had leal $-1024(%ebp),%eax to refer to s
variavle (load its pointer), right?
> If you compile with `-g', the
> compiler adds data to the object files to associate specific offsets
> with specific named parameters/variables, so that you can reference
> them by name from within the debugger.
Yeah. found that. (gcc -g -S makes the listing about 3 times bigger).
>
> If you compile with the -fomit-frame-pointer switch, the entry code
> isn't generated. Instead, parameters and local variables are
> referenced relative to esp.
I see. I wonder why frames (if i use this word right here) were involved
at all.,.. except making things easier for debuggers, i don't see much
profit of it.. maybe i am having something out of my sight?
> The purpose of the -fomit-frame-pointer switch is to make an extra
> register (ebp) available for use within the function. On the Intel
> processors, which have very few registers compared to most other
> architectures, this can provide a significant increase in performance
> for certain types of code.
like which?
> Incidentally, the Intel processors have dedicated `enter' and `leave'
Yeah. I found it in some i486-book here. Also I noted some other
high-level language commands were added there..interesting.
> instructions which do exactly the same thing as the entry and exit
> code shown above. However they are slower than the code shown above
> (on the 486 at least; I don't know the relative timings on the
> Pentium).
slower, hmm, my book says leave takes 5 clocks,
movl takes from 3 up to 16 clocks, and pop takes from 3 up to 16 clocks, I
thought leave should work faster.
and there's another question about gdb, (if you don't mind): what would
such message mean:
0x8048695 <_fini+69>: orb (%eax),%al
0x8048697 <_fini+71>: boundl 0x73(%ecx),%esp
0x804869a <_fini+74>: Cannot access memory at address 0x804869b.
.. have i reached the end of segment here?
----------
plus sometimes while doing debugs, i have "SIGFAULT in libc.XX or
some function or whatever,..thing*) how do i see where exactly things
are broken?
Thanks for your explains
--
Fyodor