Re: Activation Records on Stack Based Machines

Joachim Durchholz <joachim.durchholz@web.de>
1 Feb 2004 12:47:24 -0500

          From comp.compilers

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)
| List of all articles for this month |

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.


Post a followup to this message

Return to the comp.compilers page.
Search the comp.compilers archives again.