pgubook-readers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Pgubook-readers] Question Regarding Initial Stack Frame


From: Mark Schmid
Subject: Re: [Pgubook-readers] Question Regarding Initial Stack Frame
Date: Thu, 25 Oct 2007 21:57:39 +0200

Hi Jonathon,

I have no idea why the GCC compiler pushes the %ebp base
pointer onto the stack: I always just used "as" so far.

The point it this though: Multi-threading (which is
beyond me as well) aside, we do NOT NEED to save the
base pointer when starting our program!
If we suppose that all programs execute from start to
finish without other programs interfering with multiple
threads, there really is no need to safe the base pointer
when we start the program. Because when we start the program,
all other programs have finished and hence don't need their
base pointers any more!
Same for our program. When it's done, who needs our base
pointer? Nobody! Right?
The only ones who needs the base pointer of our main program
is our main program itself - and, again, multi threading aside,
it ONLY needs it while it is running. Before any other program
uses it, CAN use it, our program will have finished and won't
need it anymore (ignoring multi-threading)! So there's no need 
to preserve base pointers when we assume that a program has 
total control and NO other thread or operation uses any of the 
CPU's registers!

Now I do know a little about multi-threading (I read another
book as well) and perhaps this answers your question:
It's true that the processor only has one base pointer register,
%ebp. And it's also true that in a multi-thread environment
or even in an environment where a program must share control
with an operating system such as Linux or Widows, they probably
BOTH need the base pointer register intermittently while running.
What I learned from my other book was that at a task-switch which 
switches from one thread to another, ALL registers are automatically 
saved in some location and then copied back when the task (thread) 
in question is continued again.
I suppose that's what's happening with our little programs.
While Linux is running in the background and might even switch
tasks while our program is running, all registers are automatically
saved and copied back every time threads or tasks are switched.
So we really don't need to fear that someone might overwrite the
base pointer of our main program (other than our program's own
functions!).

An explanation why GCC saves the base pointer might be this:
I also read that there are different kinds of task-switches.
There are task switches between the OS and programs, between
different programs and even within a single program if it is
programmed to be set up as multiple threads / tasks.
For some task-switches, such as between OS and programs and
perhaps between two different programs, the saving and restoring
of all processor registers is carried out automatically without
having to be programmed by the programmer.
But for some other task switches, if I recall correctly, for threads
or task switches within a program (which is a different "type"
of task switch), all register values must be copied and
restored by the programmer.
That's probably why GCC is saving the base pointer.
Perhaps it's just generally assuming this is part of a 
multi-threaded program, just to be on the safe side.
If it's not, it doesn't matter, it's only one little operation,
hardly something too time consuming. If it is, the base pointer is
saved for programming a multi-threaded program.

To get the full run-down of this you'd probable have to get
a good explanation of multi-threading, the different kinds of
task switches, how they work and what standards they follow.

As said, I only have a "hunch" about this myself.

Regards,
Mark



-------- Original-Nachricht --------
> Datum: Wed, 24 Oct 2007 22:50:04 -0600
> Von: "Jonathon Donaldson" <address@hidden>
> An: "Mark Schmid" <address@hidden>, address@hidden
> Betreff: Re: [Pgubook-readers] Question Regarding Initial Stack Frame

> I understand all about the stack framing and why we need to save the
> original base pointer within a function and variables and all that
> stuff.  But why Bartlett does not push the %ebp register at the
> beginning of main is still unclear and it is not explained in Chapter
> 4.
> 
> I know that each program is provided it's own stack memory when it
> first begins execution, but there is still only one %ebp register and
> one %esp register physically inside the processor.  So my concern is
> what about the program that was running before the processor began
> execution of your program?  The previous application was also using
> the %ebp and %esp registers so it would make sense to save them and
> then return them to there original state just before exiting the main
> method of your program.
> 
> My main concern is stemming from the fact that GCC includes the
> assembly instruction to push the original %ebp register to the stack
> when it compiles the user's code.  You can see this if you compile
> this very simple program:
> 
> int main ()
> {
>   return 0;
> }
> 
> Use the command gcc -S <filename.c>
> 
> Check the resulting assembly file and you will see the "push %ebp"
> command just before it saves the stack pointer.  It includes the
> instruction no matter what C code I compile.  The good folks that
> wrote the GCC compiler must believe that it's necessary, which makes
> the most sense to me since (as I stated before) the previously running
> application would need to have its %ebp and %esp registers restored so
> it could continue execution where it left off.
> 
> I'm thinking this has something to do with multi-tasking and
> task-switching which is wayyyyy beyond where I am right now, but I
> sure would like to crack this little nut!  :-D
> 
> I'm eager to hear your thoughts.
> 
> THANKS!
> 
> Jonathon
> 
> On 10/23/07, Mark Schmid <address@hidden> wrote:
> > Hello Jonathon,
> >
> > If understand your question correctly, you asked, why
> > the base pointer %ebp is saved to the stack at the
> > beginning of a function and then popped back off
> > at the end of the function, but NOT at the beginning
> > of the program.
> > I think the answer is this:
> > There's no reason to!
> >
> > The stack pointer is saved to the base pointer
> > to set up the base pointer to point at the base
> > of the stack at the beginning of the main program.
> > That means: To the base (or top?) of the main program's
> > stack frame. The place the stack pointer was at the very
> > beginning of the program, before it was used to
> > save new variables, etc.
> > The base pointer is just a copy of the stack pointer
> > when that is at the "base" such as when the main
> > program or a function starts.
> >
> > We save the base pointer address on the stack
> > when we start a function, so we can use the
> > base pointer register as a base pointer for
> > that function's stack values. - WITHOUT loosing
> > the base pointer of the main program!
> >
> > Remember the "stack frame"? Both the main
> > program and each function have a "stack frame",
> > that is a set of variables (parameters or arguments)
> > which are used by the program or function and which
> > are passed to it by saving them on the stack.
> > (Manually in case of functions, by LINUX in case of
> > the main program.)
> > The base pointer register is used as a "ground 0",
> > from where the offset of each variable gives the
> > stack address of the wanted variable on the stack.
> >
> > HOWEVER: We are using the SAME stack both for the
> > main program AND all functions. So the main program
> > and all functions must have their stack frame or
> > variables saved at different locations on the stack.
> > The base pointer just points at the base address of
> > the corresponding current code. At the base stack
> > address for the main program in the main program
> > and at the base stack address of a function during
> > that function.
> > Since we are returning to the main program after all
> > functions, we might NEED the base pointer of the main
> > program AGAIN to access arguments / parameters / variables
> > of the main program saved on the stack.
> > But if we used the base pointer as the base for a function's
> > stack frame (which is a different address), we would have
> > lost our base pointer value for the main program!!! HELP!!
> > ;-)
> > That's why we save the base pointer on the stack in
> > every function BEFORE we set it to that current function's
> > stack base (pointer).
> > Then when we return to the main program, we restore the
> > base pointer (register) to what it was before calling
> > the function, namely the main program's stack base address
> > (or ground 0 of it's stack frame).
> >
> > Why don't we save the base pointer on the stack at the
> > beginning of the main program?
> > EASY: Because when we are done with the main program,
> > we do NOT NEED to restore the base pointer to anything
> > it could have been before the main program was started.
> >
> > When the main program ends, EVERYTHING of that program,
> > including the entire stack is destroyed.
> > All that remains of the main program is the return value
> > passed by the interrupt call.
> >
> > I hope this wasn't confusing.
> > If it is, I suggest you re-read chapter 4 about functions
> > very carefully and pay attention why the base pointer
> > is saved and what exactly it actually is and what it's
> > needed for.
> > Hope that helps.
> >
> > Regards,
> > Mark
> >
> >
> >
> >
> >
> > -------- Original-Nachricht --------
> > > Datum: Sun, 21 Oct 2007 11:46:36 -0600
> > > Von: "Jonathon Donaldson" <address@hidden>
> > > An: address@hidden
> > > Betreff: [Pgubook-readers] Question Regarding Initial Stack Frame
> >
> > > Well, I tried to search the pgubook mailing list archives for an
> > > answer to this question but it seems to be "out of order".  I've been
> > > receiving "404 Not Found" for the last few days.  I've also looked on
> > > Google but can't seem to find any specific answer, but I might not be
> > > using the correct terms.  So forgive me if this question has already
> > > been answered.
> > >
> > > At the very beginning of the main method for the programs provided in
> > > Chapters 5 (toupper.s) and 6 (read-records.s) the very first
> > > instruction saves the stack pointer using the instruction:
> > >
> > > movl %esp, %ebp
> > >
> > > However, Bartlett neglects to push the original %ebp register to the
> > > stack beforehand.  I doubt this is a bug as he does this on more than
> > > one occasion.  I have looked everywhere for a reason as to why the
> > > "push %ebp" instructions is always used first inside functions but not
> > > within the main method.
> > >
> > > Why do we not have to save the original base pointer register before
> > > we destroy it in the main method?
> > >
> > > I hope there is still someone listening out there.  Thanks in advance
> > > for your help!
> > >
> > > --
> > > Jonathon
> > >
> > >
> > > _______________________________________________
> > > Pgubook-readers mailing list
> > > address@hidden
> > > http://lists.nongnu.org/mailman/listinfo/pgubook-readers
> >
> > --
> > Psssst! Schon vom neuen GMX MultiMessenger gehört?
> > Der kanns mit allen: http://www.gmx.net/de/go/multimessenger
> >
> 
> 
> -- 
> Jonathon W. Donaldson

-- 
Der GMX SmartSurfer hilft bis zu 70% Ihrer Onlinekosten zu sparen! 
Ideal für Modem und ISDN: http://www.gmx.net/de/go/smartsurfer




reply via email to

[Prev in Thread] Current Thread [Next in Thread]