// MEMORY · WHAT'S UNDERNEATH //
A pointer is just an address you stored somewhere
Pointers are where a lot of people quietly decide programming isn't for them. The asterisks, the arrows, *p versus &p. The 6502 strips all of it away, because here a pointer isn't a type or a concept — it's two bytes in memory holding an address, and one addressing mode that goes and reads it.
Store an address like any other number
Put the address $C000 into two bytes of zero page — low byte, then high byte, the 6502’s usual order. Those two bytes are now a pointer. Not “like” a pointer — they hold an address, which is the entire definition.
lda #$00
sta $10 ; $10 = low byte of $C000
lda #$c0
sta $11 ; $11 = high byte of $C000
; the pair $10/$11 now "points to" $C000p = &thing, with the curtain up.Dereferencing is one addressing mode
To follow the pointer — to read the byte it points at — you use indirect indexed addressing: lda ($10),y. The CPU reads the address out of $10/$11, adds Y, and fetches from there. That little ( ) is the asterisk in *p:
ldy #0
loop: lda ($10),y ; A = *(p + y) — dereference
beq done ; zero byte ends the string
jsr print
iny ; y++ — walk one byte along
bne loop
done: rtsY and you're doing pointer arithmetic. Change $10/$11 and the same loop walks a different array.Every pointer idea is now standing in the open. A null pointer is the pair holding $0000 — dereference it and you read address zero, garbage, no guard rail. A dangling pointer is two bytes still holding an address whose data you’ve since reused. A pointer to a pointer is a pointer whose target happens to be another two-byte address. None of it is abstract here — it’s just which bytes hold which addresses.
The asterisk was never the hard part — it was the abstraction hiding the bytes. Once you’ve set a pointer with two
stas and followed it with onelda ($10),y, the C melts. A pointer is an address you stored somewhere. That’s the whole secret.