Pointers and Indirection

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 the Chapter called Structured Programming This essay seeks to explain the uses of the indirect modes, and how to implement pointer operations with them. It does not 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.

The absolute basics

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 "pure" indirect modes (except for JMP, which is a matter for a later essay); all are indexed, and they're indexed different ways depending on which index register you use.

The simplest example

When doing a simple, direct dereference (that is, something equivalent to the C code c=*b;) the code looks like this:

        ldy #0
        lda (b), y
        sta c

Even with this simple example, there are several important things to notice.

  • The variable b must be on the zero page, and furthermore, it cannot be $FF. All your pointer values need to be either stored on the zero page to begin with or copied there before use.

  • The y in the lda 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.

  • The b variable is used alone. Statements like lda (b+2), y are syntactically valid and sometimes even correct: it dereferences the value next to b after adding y to the value therein. However, it is almost guaranteed that what you *really* wanted to do was compute *(b+2) (that is, take the address of b, add 2 to that, and dereference that value); see the next section for how to do this properly.

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.