Memory organisation of the Z80 Turbo Pascal compiler

Lasse =?iso-8859-1?q?Hiller=F8e?= Petersen <lhp+news@toft-hp.dk>
29 Sep 2021 11:40:20 GMT

          From comp.compilers

Related articles
Memory organisation of the Z80 Turbo Pascal compiler lhp+news@toft-hp.dk (Lasse =?iso-8859-1?q?Hiller=F8e?= Petersen) (2021-09-29)
Re: Memory organisation of the Z80 Turbo Pascal compiler DrDiettrich1@netscape.net (Hans-Peter Diettrich) (2021-09-30)
Re: Memory organisation of the Z80 Turbo Pascal compiler lhp+news@toft-hp.dk (Lasse =?iso-8859-1?q?Hiller=F8e?= Petersen) (2021-10-02)
Re: Memory organisation of the Z80 Turbo Pascal compiler gah4@u.washington.edu (gah4) (2021-10-02)
Re: Memory organisation of the Z80 Turbo Pascal compiler anton@mips.complang.tuwien.ac.at (2021-10-02)
Re: Memory organisation of the Z80 Turbo Pascal compiler DrDiettrich1@netscape.net (Hans-Peter Diettrich) (2021-10-03)
| List of all articles for this month |
From: Lasse =?iso-8859-1?q?Hiller=F8e?= Petersen <lhp+news@toft-hp.dk>
Newsgroups: comp.compilers
Date: 29 Sep 2021 11:40:20 GMT
Organization: SunSITE.dk - Supporting Open source
Injection-Info: gal.iecc.com; posting-host="news.iecc.com:2001:470:1f07:1126:0:676f:7373:6970"; logging-data="74574"; mail-complaints-to="abuse@iecc.com"
Keywords: Pascal, history, question
Posted-Date: 29 Sep 2021 17:09:53 EDT

I have been thinking about the old TurboPascal compiler (actually about
its predecessor COMPAS Pascal, which I used long ago, but I believe the
original Z80 CP/M TurboPascal was exactly the same in this regard.)


In the TP 2.0 manual it says:
    "The recursion stack is used only by recursive procedures and
    functions, i.e. procedures and functions compiled with the
    A compiler directive passive (~A-}). On entry to a recursive
    subprogram it copies its workspace onto the recursion stack,
    and on exit the entire workspace is restored to its original
    state. The default initial value of RecurPtr at the beginning
    of a program, is 1 K ($400) bytes below the CPU stack pointer."


In other words, all procedures in a program have their own statically
located "workspace", and when recursive calls are made, the previously
activation's local variables are saved away. I suppose this was practical
on the Z80, because indexed operations were rather expensive and not
relative to SP, using the separate IX and IY registers, whereas an LDIR
instruction was reasonably efficient.


As far as I can tell, this works great even for a language with nested
lexical scope like Pascal. When an inner procedure refers to a containing
procedure's local variable, it will get the currently active instance.


However, I think there would be an issue when passing procedure local
variables as VAR parameters in combination with some forms of mutual and/
or nested recursion, as the address passed would refer to the right
workspace, but the workspace might contain the wrong activation instance.
I'm not completely sure about this, and I don't have a setup at the
moment where I could experiment and test it.


In any case, I have never found any description of this style of scope
management, since I actually used this compiler back in the 80es, and I
don't know if it even has a name?


Other than the copying (which may be considered inefficient, but only
applies to recursive procedures) and the possible issue with passing
references ending up pointing to the wrong variable, what would be the
pros and cons of this method?


/Lasse


Post a followup to this message

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