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.
Back in Unit 4 you met the eight address registers, a0–a7, 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:
a0on 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 stepsa0along 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
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 a0 — lea 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
.wsomewhere 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.
leaneeds 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.