2012-06-16 09:07:47 +00:00
|
|
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
|
|
<HTML
|
|
|
|
><HEAD
|
|
|
|
><TITLE
|
|
|
|
>Pointers and Indirection</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="To HLL and Back"
|
2014-05-25 08:46:17 +00:00
|
|
|
HREF="p618.html"><LINK
|
2012-06-16 09:07:47 +00:00
|
|
|
REL="PREVIOUS"
|
|
|
|
TITLE="A modest example: Insertion sort on linked lists"
|
2014-05-25 08:46:17 +00:00
|
|
|
HREF="x856.html"><LINK
|
2012-06-16 09:07:47 +00:00
|
|
|
REL="NEXT"
|
|
|
|
TITLE="Pointer arithmetic"
|
2014-05-25 08:46:17 +00:00
|
|
|
HREF="x919.html"></HEAD
|
2012-06-16 09:07:47 +00:00
|
|
|
><BODY
|
|
|
|
CLASS="CHAPTER"
|
|
|
|
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
|
2014-05-25 08:46:17 +00:00
|
|
|
HREF="x856.html"
|
2012-06-16 09:07:47 +00:00
|
|
|
ACCESSKEY="P"
|
|
|
|
><<< Previous</A
|
|
|
|
></TD
|
|
|
|
><TD
|
|
|
|
WIDTH="80%"
|
|
|
|
ALIGN="center"
|
|
|
|
VALIGN="bottom"
|
|
|
|
></TD
|
|
|
|
><TD
|
|
|
|
WIDTH="10%"
|
|
|
|
ALIGN="right"
|
|
|
|
VALIGN="bottom"
|
|
|
|
><A
|
2014-05-25 08:46:17 +00:00
|
|
|
HREF="x919.html"
|
2012-06-16 09:07:47 +00:00
|
|
|
ACCESSKEY="N"
|
|
|
|
>Next >>></A
|
|
|
|
></TD
|
|
|
|
></TR
|
|
|
|
></TABLE
|
|
|
|
><HR
|
|
|
|
ALIGN="LEFT"
|
|
|
|
WIDTH="100%"></DIV
|
|
|
|
><DIV
|
|
|
|
CLASS="CHAPTER"
|
|
|
|
><H1
|
|
|
|
><A
|
|
|
|
NAME="HLL3"
|
|
|
|
></A
|
|
|
|
>Pointers and Indirection</H1
|
|
|
|
><P
|
|
|
|
> The basics of pointers versus cursors (or, at the 6502 assembler
|
|
|
|
level, the indirect indexed addressing mode versus the absolute
|
|
|
|
indexed ones) were covered in <A
|
2014-05-25 08:46:17 +00:00
|
|
|
HREF="c680.html"
|
2012-06-16 09:07:47 +00:00
|
|
|
>the Chapter called <I
|
|
|
|
>Structured Programming</I
|
|
|
|
></A
|
|
|
|
> This essay seeks
|
|
|
|
to explain the uses of the indirect modes, and how to implement
|
|
|
|
pointer operations with them. It does <I
|
|
|
|
CLASS="EMPHASIS"
|
|
|
|
>not</I
|
|
|
|
> seek to explain
|
|
|
|
why you'd want to use pointers for something to begin with; for a
|
|
|
|
tutorial on proper pointer usage, consult any decent C textbook.</P
|
|
|
|
><DIV
|
|
|
|
CLASS="SECTION"
|
|
|
|
><H1
|
|
|
|
CLASS="SECTION"
|
|
|
|
><A
|
2014-05-25 08:46:17 +00:00
|
|
|
NAME="AEN890"
|
2012-06-16 09:07:47 +00:00
|
|
|
>The absolute basics</A
|
|
|
|
></H1
|
|
|
|
><P
|
|
|
|
> A pointer is a variable holding the address of a memory location.
|
|
|
|
Memory locations take 16 bits to represent on the 6502: thus, we
|
|
|
|
need two bytes to hold it. Any decent assembler will have ways of
|
|
|
|
taking the high and low bytes of an address; use these to acquire
|
|
|
|
the raw values you need. The 6502 chip does not have any
|
|
|
|
simple <SPAN
|
|
|
|
CLASS="QUOTE"
|
|
|
|
>"pure"</SPAN
|
|
|
|
> indirect modes (except
|
|
|
|
for <TT
|
|
|
|
CLASS="LITERAL"
|
|
|
|
>JMP</TT
|
|
|
|
>, which is a matter for a later essay);
|
|
|
|
all are indexed, and they're indexed different ways depending on
|
|
|
|
which index register you use.
|
|
|
|
</P
|
|
|
|
><DIV
|
|
|
|
CLASS="SECTION"
|
|
|
|
><H2
|
|
|
|
CLASS="SECTION"
|
|
|
|
><A
|
2014-05-25 08:46:17 +00:00
|
|
|
NAME="AEN895"
|
2012-06-16 09:07:47 +00:00
|
|
|
>The simplest example</A
|
|
|
|
></H2
|
|
|
|
><P
|
|
|
|
> When doing a simple, direct dereference (that is, something
|
|
|
|
equivalent to the C code <TT
|
|
|
|
CLASS="LITERAL"
|
|
|
|
>c=*b;</TT
|
|
|
|
>) the code
|
|
|
|
looks like this:
|
|
|
|
</P
|
|
|
|
><TABLE
|
|
|
|
BORDER="0"
|
|
|
|
BGCOLOR="#E0E0E0"
|
|
|
|
WIDTH="100%"
|
|
|
|
><TR
|
|
|
|
><TD
|
|
|
|
><PRE
|
|
|
|
CLASS="PROGRAMLISTING"
|
|
|
|
> ldy #0
|
|
|
|
lda (b), y
|
|
|
|
sta c</PRE
|
|
|
|
></TD
|
|
|
|
></TR
|
|
|
|
></TABLE
|
|
|
|
><P
|
|
|
|
> Even with this simple example, there are several important
|
|
|
|
things to notice.
|
|
|
|
</P
|
|
|
|
><P
|
|
|
|
></P
|
|
|
|
><UL
|
|
|
|
><LI
|
|
|
|
><P
|
|
|
|
> The variable <TT
|
|
|
|
CLASS="LITERAL"
|
|
|
|
>b</TT
|
|
|
|
> <I
|
|
|
|
CLASS="EMPHASIS"
|
|
|
|
>must be on the
|
|
|
|
zero page</I
|
|
|
|
>, and furthermore, it <I
|
|
|
|
CLASS="EMPHASIS"
|
|
|
|
>cannot
|
|
|
|
be $FF.</I
|
|
|
|
> All your pointer values need to be
|
|
|
|
either stored on the zero page to begin with or copied
|
|
|
|
there before use.
|
|
|
|
</P
|
|
|
|
></LI
|
|
|
|
><LI
|
|
|
|
><P
|
|
|
|
> The <TT
|
|
|
|
CLASS="LITERAL"
|
|
|
|
>y</TT
|
|
|
|
> in the <TT
|
|
|
|
CLASS="LITERAL"
|
|
|
|
>lda</TT
|
|
|
|
>
|
|
|
|
statement must be y. It cannot be x (that's a different
|
|
|
|
form of indirection), and it cannot be a constant. If
|
|
|
|
you're doing a lot of indirection, be sure to keep your Y
|
|
|
|
register free to handle the indexing on the
|
|
|
|
pointers.
|
|
|
|
</P
|
|
|
|
></LI
|
|
|
|
><LI
|
|
|
|
><P
|
|
|
|
> The <TT
|
|
|
|
CLASS="LITERAL"
|
|
|
|
>b</TT
|
|
|
|
> variable is used alone. Statements
|
|
|
|
like <TT
|
|
|
|
CLASS="LITERAL"
|
|
|
|
>lda (b+2), y</TT
|
|
|
|
> are syntactically valid
|
|
|
|
and sometimes even correct: it dereferences the value next
|
|
|
|
to <TT
|
|
|
|
CLASS="LITERAL"
|
|
|
|
>b</TT
|
|
|
|
> after adding y to the value therein.
|
|
|
|
However, it is almost guaranteed that what you *really*
|
|
|
|
wanted to do was compute <TT
|
|
|
|
CLASS="LITERAL"
|
|
|
|
>*(b+2)</TT
|
|
|
|
> (that is,
|
|
|
|
take the address of b, add 2 to <I
|
|
|
|
CLASS="EMPHASIS"
|
|
|
|
>that</I
|
|
|
|
>,
|
|
|
|
and dereference that value); see the next section for how to
|
|
|
|
do this properly.
|
|
|
|
</P
|
|
|
|
></LI
|
|
|
|
></UL
|
|
|
|
><P
|
|
|
|
> In nearly all cases, it is the Y-register's version (Indirect
|
|
|
|
Indexed) that you want to use when you're dealing with pointers.
|
|
|
|
Even though either version could be used for this example, we
|
|
|
|
use the Y register to establish this habit.
|
|
|
|
</P
|
|
|
|
></DIV
|
|
|
|
></DIV
|
|
|
|
></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
|
2014-05-25 08:46:17 +00:00
|
|
|
HREF="x856.html"
|
2012-06-16 09:07:47 +00:00
|
|
|
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
|
2014-05-25 08:46:17 +00:00
|
|
|
HREF="x919.html"
|
2012-06-16 09:07:47 +00:00
|
|
|
ACCESSKEY="N"
|
|
|
|
>Next >>></A
|
|
|
|
></TD
|
|
|
|
></TR
|
|
|
|
><TR
|
|
|
|
><TD
|
|
|
|
WIDTH="33%"
|
|
|
|
ALIGN="left"
|
|
|
|
VALIGN="top"
|
|
|
|
>A modest example: Insertion sort on linked lists</TD
|
|
|
|
><TD
|
|
|
|
WIDTH="34%"
|
|
|
|
ALIGN="center"
|
|
|
|
VALIGN="top"
|
|
|
|
><A
|
2014-05-25 08:46:17 +00:00
|
|
|
HREF="p618.html"
|
2012-06-16 09:07:47 +00:00
|
|
|
ACCESSKEY="U"
|
|
|
|
>Up</A
|
|
|
|
></TD
|
|
|
|
><TD
|
|
|
|
WIDTH="33%"
|
|
|
|
ALIGN="right"
|
|
|
|
VALIGN="top"
|
|
|
|
>Pointer arithmetic</TD
|
|
|
|
></TR
|
|
|
|
></TABLE
|
|
|
|
></DIV
|
|
|
|
></BODY
|
|
|
|
></HTML
|
|
|
|
>
|