Skip to content
Game 0 Unit 11 of 19 1 hr learning time

Pointers and the Address Registers

An address register holds an address, not a number — and with brackets, (a0) means "the box a0 points at". Add the + and reading also steps the pointer on. Walk a pointer along a table and you can process a list of anything.

58% of Meet The Machine

Back in Unit 4 you met the eight address registers, a0a7, and the rule that they hold addresses — places in memory — not values. Unit 5 used one to reach a fixed spot. Now we put them to their real work: walking through a list.

A register that holds an address is a pointer. The brackets are how you follow it:

  • a0 on its own is the address — the slip of paper with a house number on it.
  • (a0) means the box at that address — what's stored there.
  • (a0)+ reads the box and then steps a0 along to the next one, in a single instruction.

That little + is what turns a list into a walk. Read, step, read, step — the pointer crawls along a row of data and you touch each item in turn. Tables of enemies, strings of letters, a level laid out in memory: all of them are walked with a pointer.

What you'll see by the end

The Amiga screen filled with solid violet.
Violet — the third colour in a table of four, reached by stepping a pointer twice and reading the box it lands on.

A violet screen. There's a table of four colours sitting in memory; the code starts a pointer at the front, steps it along, and shows the third entry. Change where the pointer stops and a different colour fills the screen.

Walk the pointer

;──────────────────────────────────────────────────────────────
; Meet the Machine (Amiga) - Unit 11: Pointers and the Address Registers
;
; An address register holds an address - and with brackets, (a0) means "the box
; a0 points at". (a0)+ reads it AND steps the pointer to the next box. Here a
; pointer walks along a table of colours, reading as it goes.
;──────────────────────────────────────────────────────────────

CUSTOM      equ $dff000
DMACON      equ $096
INTENA      equ $09a
INTREQ      equ $09c
COP1LC      equ $080
COPJMP1     equ $088
BPLCON0     equ $100
COLOR00     equ $180

            section code,code_c

start:
            lea     CUSTOM,a5
            move.w  #$7fff,INTENA(a5)
            move.w  #$7fff,INTREQ(a5)
            move.w  #$7fff,DMACON(a5)
            lea     copperlist,a0
            move.l  a0,COP1LC(a5)
            move.w  d0,COPJMP1(a5)
            move.w  #$8280,DMACON(a5)

            ; ----------------------------------------------- YOUR CODE START
            lea     colours,a0          ; a0 points at the start of the table
            move.w  (a0)+,d0            ; read colours[0], then step a0 on
            move.w  (a0)+,d0            ; read colours[1], then step on
            move.w  (a0),d0             ; read colours[2] (no step this time)
            move.w  d0,colourval        ; show it
            ; ------------------------------------------------- YOUR CODE END

forever:
            bra.s   forever

colours:    dc.w    $0f80, $00ff, $0a0f, $0ff0   ; a table of colours in memory

copperlist:
            dc.w    BPLCON0,$0200
            dc.w    COLOR00
colourval:
            dc.w    $0000
            dc.w    $ffff,$fffe

The table is one line of data:

colours:    dc.w    $0f80, $00ff, $0a0f, $0ff0   ; four colours in memory

dc.w lays four 16-bit words down in memory, back to back. colours is a label for the address of the first one. The walk reads them:

lea     colours,a0          ; a0 points at the start of the table
move.w  (a0)+,d0            ; read colours[0], then step a0 on
move.w  (a0)+,d0            ; read colours[1], then step on
move.w  (a0),d0             ; read colours[2] (no step this time)
move.w  d0,colourval        ; show it

lea colours,a0 loads the address of the table into a0lea means "load effective address," and it's how you put a pointer somewhere. Each move.w (a0)+,d0 reads the word a0 points at into d0, then advances a0 by two bytes — one word — so it's aimed at the next entry. After two steps the pointer sits on the third colour, and the last read uses plain (a0) with no + because we're done walking. $0a0f — strong red, no green, full blue — is violet, and that's what reaches the screen.

The pointer did the bookkeeping. You never wrote a single address yourself after the first lea; the + kept count.

Assemble, master, and run

make

A violet screen — the third entry in the table.

Try this: pick a different entry

Add a third move.w (a0)+,d0 to step once more, then read. Now you land on $0ff0 — yellow, the fourth colour. Each (a0)+ you add walks one box further along the list.

Try this: change the table

Edit the dc.w line — put your own colours in, or add more entries. The pointer doesn't care how long the table is or what's in it; it just steps from one word to the next. That indifference is the point: the same walking code handles a list of any length.

If it doesn't work

  • The wrong colour shows. Count your (a0)+ steps. Each one moves the pointer forward by one entry, so two steps before a read lands on the third colour, not the second.
  • The colours look scrambled. A .w somewhere became a .l, so the pointer stepped four bytes instead of two and read across two entries at once. Each colour is a word — keep the reads .w.
  • It won't assemble. lea needs an address and an address register: lea colours,a0. Loading into a data register, or forgetting the label, both fail here.

What you've learnt

An address register holds a pointer — an address, not a value. (a0) reaches the box it points at; (a0)+ reads that box and steps the pointer on in one instruction. lea loads an address into a register to get started. Walk a pointer along a table with (a0)+ and you process a list of any length without ever counting addresses by hand.

What's next

You stepped the pointer by writing the move out three times. That doesn't scale to a hundred entries. Next — The Counted Loop — the 68000's DBRA instruction repeats a block a set number of times, so one short loop can walk a table of any size.