> 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

Reply via email to