mirror of
https://github.com/michaelcmartin/Ophis.git
synced 2024-11-18 11:06:07 +00:00
283 lines
4.8 KiB
HTML
283 lines
4.8 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
<HTML
|
|
><HEAD
|
|
><TITLE
|
|
>Procedures and register saving</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="Structured Programming"
|
|
HREF="c680.html"><LINK
|
|
REL="PREVIOUS"
|
|
TITLE="The stack"
|
|
HREF="x734.html"><LINK
|
|
REL="NEXT"
|
|
TITLE="Variables"
|
|
HREF="x758.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="x734.html"
|
|
ACCESSKEY="P"
|
|
><<< Previous</A
|
|
></TD
|
|
><TD
|
|
WIDTH="80%"
|
|
ALIGN="center"
|
|
VALIGN="bottom"
|
|
>Structured Programming</TD
|
|
><TD
|
|
WIDTH="10%"
|
|
ALIGN="right"
|
|
VALIGN="bottom"
|
|
><A
|
|
HREF="x758.html"
|
|
ACCESSKEY="N"
|
|
>Next >>></A
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
><HR
|
|
ALIGN="LEFT"
|
|
WIDTH="100%"></DIV
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><H1
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN740"
|
|
>Procedures and register saving</A
|
|
></H1
|
|
><P
|
|
> All programming languages are designed around the concept of
|
|
procedures.<A
|
|
NAME="AEN743"
|
|
HREF="#FTN.AEN743"
|
|
><SPAN
|
|
CLASS="footnote"
|
|
>[1]</SPAN
|
|
></A
|
|
>
|
|
Procedures let you break a computation up into different parts,
|
|
then use them independently. However, compilers do a lot of work
|
|
for you behind the scenes to let you think this. Consider the
|
|
following assembler code. How many times does the loop
|
|
execute?
|
|
</P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
>loop: ldx #$10 jsr do'stuff dex bne loop</PRE
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
><P
|
|
> The correct answer is <SPAN
|
|
CLASS="QUOTE"
|
|
>"I don't know, but
|
|
it <I
|
|
CLASS="EMPHASIS"
|
|
>should</I
|
|
> be 16."</SPAN
|
|
> The reason we don't
|
|
know is because we're assuming here that
|
|
the <TT
|
|
CLASS="LITERAL"
|
|
>do'stuff</TT
|
|
> routine doesn't change the value
|
|
of the X register. If it does, than all sorts of chaos could
|
|
result. For major routines that aren't called often but are
|
|
called in places where the register state is important, you should
|
|
store the old registers on the stack with code like this:
|
|
</P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
>do'stuff:
|
|
pha
|
|
txa
|
|
pha
|
|
tya
|
|
pha
|
|
|
|
;; Rest of do'stuff goes here
|
|
|
|
pla
|
|
tay
|
|
pla
|
|
tax
|
|
pla
|
|
rts</PRE
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
><P
|
|
> (Remember, the last item pushed onto the stack is the first one
|
|
pulled off, so you have to restore them in reverse order.) That's
|
|
three more bytes on the stack, so you don't want to do this if you
|
|
don't absolutely have to. If <TT
|
|
CLASS="LITERAL"
|
|
>do'stuff</TT
|
|
>
|
|
actually <I
|
|
CLASS="EMPHASIS"
|
|
>doesn't</I
|
|
> touch X, there's no need to
|
|
save and restore the value. This technique is
|
|
called <I
|
|
CLASS="EMPHASIS"
|
|
>callee-save</I
|
|
>.
|
|
</P
|
|
><P
|
|
> The reverse technique is called <I
|
|
CLASS="EMPHASIS"
|
|
>caller-save</I
|
|
>
|
|
and pushes important registers onto the stack before the routine
|
|
is called, then restores them afterwards. Each technique has its
|
|
advantages and disadvantages. The best way to handle it in your
|
|
own code is to mark at the top of each routine which registers
|
|
need to be saved by the caller. (It's also useful to note things
|
|
like how it takes arguments and how it returns values.)
|
|
</P
|
|
></DIV
|
|
><H3
|
|
CLASS="FOOTNOTES"
|
|
>Notes</H3
|
|
><TABLE
|
|
BORDER="0"
|
|
CLASS="FOOTNOTES"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
WIDTH="5%"
|
|
><A
|
|
NAME="FTN.AEN743"
|
|
HREF="x740.html#AEN743"
|
|
><SPAN
|
|
CLASS="footnote"
|
|
>[1]</SPAN
|
|
></A
|
|
></TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
WIDTH="95%"
|
|
><P
|
|
>Yes, all of them. Functional languages
|
|
just let you do more things with them, logic programming has
|
|
implicit calls to query procedures, and
|
|
object-oriented <SPAN
|
|
CLASS="QUOTE"
|
|
>"methods"</SPAN
|
|
> are just normal procedures
|
|
that take one extra argument in secret.</P
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
><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="x734.html"
|
|
ACCESSKEY="P"
|
|
><<< 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="x758.html"
|
|
ACCESSKEY="N"
|
|
>Next >>></A
|
|
></TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
WIDTH="33%"
|
|
ALIGN="left"
|
|
VALIGN="top"
|
|
>The stack</TD
|
|
><TD
|
|
WIDTH="34%"
|
|
ALIGN="center"
|
|
VALIGN="top"
|
|
><A
|
|
HREF="c680.html"
|
|
ACCESSKEY="U"
|
|
>Up</A
|
|
></TD
|
|
><TD
|
|
WIDTH="33%"
|
|
ALIGN="right"
|
|
VALIGN="top"
|
|
>Variables</TD
|
|
></TR
|
|
></TABLE
|
|
></DIV
|
|
></BODY
|
|
></HTML
|
|
> |