Ophis/book/x915.html
2012-06-16 02:07:47 -07:00

336 lines
6.2 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>Our Goals</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="Call Stacks"
HREF="c900.html"><LINK
REL="PREVIOUS"
TITLE="Call Stacks"
HREF="c900.html"><LINK
REL="NEXT"
TITLE="Example: Fibonnacci Numbers"
HREF="x967.html"></HEAD
><BODY
CLASS="SECTION"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="c900.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Call Stacks</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x967.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="AEN915"
>Our Goals</A
></H1
><P
> The system we develop should have all of the following
characteristics.
</P
><P
></P
><UL
><LI
><P
>It should be <I
CLASS="EMPHASIS"
>intuitive to program for</I
>. The procedure bodies should be easily readable and writable by humans, even in assembler form.</P
></LI
><LI
><P
>It should be <I
CLASS="EMPHASIS"
>efficient</I
>. Variable accesses are very common, so procedures shouldn't cost much to run.</P
></LI
><LI
><P
>It should allow <I
CLASS="EMPHASIS"
>multiple arity</I
> in both arguments and return values. We won't require that an unlimited amount of information be passable, but it should allow more than the three bytes the registers give us.</P
></LI
><LI
><P
>It should permit <I
CLASS="EMPHASIS"
>tail call elimination</I
>, an optimization that will allow certain forms of recursion to actually not grow the stack.</P
></LI
></UL
><P
> Here is a system that meets all these properties.
</P
><P
></P
><UL
><LI
><P
>Reserve two bytes of the zero page for a stack pointer. At the beginning of the program, set it to the top of memory.</P
></LI
><LI
><P
>Divide the remainder of Zero Page into two parts:
<P
></P
><UL
><LI
><P
>The <I
CLASS="EMPHASIS"
>scratch space</I
>, which is where arguments and return values go, and which may be scrambled by any function call, and</P
></LI
><LI
><P
>The <I
CLASS="EMPHASIS"
>local area</I
>, which all functions must restore to their initial state once finished.</P
></LI
></UL
>
</P
></LI
><LI
><P
>Assign to each procedure a <I
CLASS="EMPHASIS"
>frame size</I
> S, which is a maximum size on the amount of the local area the procedure can use. The procedure's variables will sit in the first S bytes of the local area.</P
></LI
><LI
><P
>Upon entering the procedure, push the first S bytes of the local area onto the stack; upon exit, pop hose S bytes back on top of the local area.</P
></LI
><LI
><P
>While the procedure is running, only touch the local area and the scratch space.</P
></LI
></UL
><P
>This meets our design criteria neatly:</P
><P
></P
><UL
><LI
><P
>It's as intuitive as such a system will get. You have to call <TT
CLASS="LITERAL"
>init'stack</TT
> at the beginning, and you need to ensure that <TT
CLASS="LITERAL"
>save'stack</TT
> and <TT
CLASS="LITERAL"
>restore'stack</TT
> are called right. The procedure's program text can pretend that it's just referring to its own variables, just like with the old style. If a procedure doesn't call <I
CLASS="EMPHASIS"
>anyone</I
>, then it can just do all its work in the scratch space.</P
></LI
><LI
><P
>It's efficient; the inside of the procedure is likely to be faster and smaller than its FORTRAN-style counterpart, because all variable references are on the Zero Page.</P
></LI
><LI
><P
>Both arguments and return values can be as large as the scratch space. It's not infinite, but it's probably good enough.</P
></LI
><LI
><P
>Tail call elimination is possible; just restore the stack before making the JMP to the tail call target.</P
></LI
></UL
><P
> The necessary support code is pretty straightforward. The stack
modification routines take the size of the frame in the
accumulator, and while saving the local area, it copies over the
corresponding values from the scratch space. (This is because
most functions will be wanting to keep their arguments around
across calls.)
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>.scope
; Stack routines
.data zp
.space _sp $02
.space _counter $01
.space fun'args $10
.space fun'vars $40
.text
init'stack:
lda #$00
sta _sp
lda #$A0
sta _sp+1
rts
save'stack:
sta _counter
sec
lda _sp
sbc _counter
sta _sp
lda _sp+1
sbc #$00
sta _sp+1
ldy #$00
* lda fun'vars, y
sta (_sp), y
lda fun'args, y
sta fun'vars, y
iny
dec _counter
bne -
rts
restore'stack:
pha
sta _counter
ldy #$00
* lda (_sp), y
sta fun'vars, y
iny
dec _counter
bne -
pla
clc
adc _sp
sta _sp
lda _sp+1
adc #$00
sta _sp+1
rts
.scend</PRE
></TD
></TR
></TABLE
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="c900.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x967.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Call Stacks</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="c900.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Example: Fibonnacci Numbers</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>