Related articles |
---|
Activation Records on Stack Based Machines io@spunge.org (2004-01-22) |
Re: Activation Records on Stack Based Machines torbenm@diku.dk (2004-01-31) |
Re: Activation Records on Stack Based Machines anton@mips.complang.tuwien.ac.at (2004-01-31) |
Re: Activation Records on Stack Based Machines basile-news@starynkevitch.net (Basile Starynkevitch \[news\]) (2004-01-31) |
Re: Activation Records on Stack Based Machines joachim.durchholz@web.de (Joachim Durchholz) (2004-02-01) |
Re: Activation Records on Stack Based Machines ftu@fi.uu.nl (2004-02-01) |
Re: Activation Records on Stack Based Machines rbates@southwind.net (Rodney M. Bates) (2004-02-04) |
From: | Joachim Durchholz <joachim.durchholz@web.de> |
Newsgroups: | comp.compilers |
Date: | 1 Feb 2004 12:47:24 -0500 |
Organization: | Oberberg Online Infosysteme |
References: | 04-01-129 |
Keywords: | architecture |
Posted-Date: | 01 Feb 2004 12:47:24 EST |
leibniz wrote:
> Where do I place the return value of a function, save program
> counter, allocate space for local variables...etc. Can someone give
> me pointers on how that can be done on stack-based machines?
Any basic text would do. Actually, the issues for virtual and real
machines vary only marginally.
The usual order on stack is:
* parameters
* space for the return value (if needed)
* return address
* local variables
Parameters and return address are the bare minimum, and are the
activation record proper: a recording of what the subroutine is
supposed to work with (the parameters) and where execution is supposed
to continue after it's done (the return address). By extension,
return value space and local variables are also often included in the
term "activation record".
In practice, there's often an additional entry, either before or after
the return address: the caller's "frame pointer". The frame pointer is
a register in a real machine (or a variable in the interpreter in a
virtual one) that says where the parameter block starts. This can be
handy when the stack below the local variables grows and shrinks, it's
easier to generate code than having to determine the offsets from an
every-changing top-of-stack pointer. (A frame pointer isn't strictly
necessary unless you're doing unusual things with the local variables'
sizes.)
The above order derives from the calling sequence.
First, the caller will push the parameters, one by one. This means that
the parameters are first on the stack.
Then, the caller will jump to the subroutine. Since the subroutine has
no way of knowing where the jump came from, the caller will have to push
the return address. So the jump address goes next. (Of course, the
caller could push the return address first, but code generation is more
difficult: the code generator doesn't know where the return address will
be until it has generated the code for the rest of the calling sequence.)
The callee has no place to store the local variables except after the
return address, so there isn't much room for variation either.
The space for the return value, saved registers (if any) and saved frame
pointer values can be allocated on an ad-hoc fashion. The questions to
be answered are always the same:
* Who can provide the value: the caller or the callee?
* When during the calling sequence is it easiest to provide that value?
* Who needs the value, and when: the caller or the callee?
Usually, systematically answering these questions will also determine
where in the stack block the specific value will go, with little room
for variation.
Regards,
Jo
--
Currently looking for a new job.
Return to the
comp.compilers page.
Search the
comp.compilers archives again.