6502 assembly syntax
Assembly is the most direct way to talk to the 6502: one short line for each step the chip takes. Before it can run, a program called an assembler turns those lines into the raw bytes the processor actually executes — CodeLab uses one named go6asm. Everything you can write in CodeLab is on this page, and that's the whole point: it's a small vocabulary, on purpose.
A real 6502 program carries a lot of bookkeeping around it — deciding where in memory the program lives, and telling the chip how to find it the instant it powers on. CodeLab fills all of that in for you, so your attention goes to the instructions themselves and not the plumbing. This simplified way of writing — just the instructions, none of the scaffolding — has a name: we call it Layer-0. Under the hood your short program is expanded into a complete, valid 6502 program; that fuller version is exactly what you see in the hex dump and disassembly. Want the bigger picture — the registers, how the chip finds your code, the memory map? See More about the 6502.
One more bit of help: every time you assemble, the editor lines your code up onto a tidy, consistent grid. Don't fuss over spacing — type it however you like and let CodeLab make it neat.
The shape of a program
- One instruction per line. Whitespace doesn't matter; the formatter fixes alignment.
- Comments start with
;and run to end of line. A whole line can be a comment. - No setup needed. CodeLab decides where your program lives in memory and wires up how the chip starts it — you write none of that. Begin with your first instruction.
- A 6502 never ends. Give it somewhere to spin —
the park idiom:
done: JMP done. CodeLab detects a park and stops cleanly.
; a full-line comment
LDA #$2A ; load the number 42 into A
STA ViaBase ; show it on the 8 LEDs
done: JMP done ; park here forever Labels & symbols
- Define a label by writing
name:— it marks the address of the next instruction. Use the bare name as an operand (JMP loop,BNE loop). - Names are letters, digits and
_, not starting with a digit.@local:is a short-lived local label. ViaBaseis built in: it equals$B000, the VIA's Port B. Storing a byte there lights the 8 LEDs — bit 7 on the left, bit 0 on the right.
Numbers
$2A— hexadecimal ·%00101010— binary ·42— decimal. All the same value.#means the number itself (immediate):LDA #$2Aloads 42. Without#it's an address:LDA $2Aloads from memory location $2A.
Addressing modes
| Mode | Looks like | Meaning |
|---|---|---|
| Immediate | LDA #$2A | The number itself. `#` = literal value. |
| Absolute | STA ViaBase / STA $B000 | A 16-bit address (a label or `$nnnn`). |
| Zero page | LDA $10 | An address in $00–$FF (one byte, faster). |
| Indexed | LDA table,X | Address + the X (or Y) register. |
| Implied | INX | No operand — the instruction says it all. |
| Relative | BNE loop | A branch target (a label); the assembler computes the offset. |
Instructions used in these labs
| Group | Mnemonics | What they do |
|---|---|---|
| Load / store | LDA LDX LDY STA STX STY | Move a byte between A/X/Y and memory. |
| Count | INX INY DEX DEY INC DEC | Add or subtract 1 (registers, or a memory cell). |
| Math | ADC SBC | Add / subtract with carry (clear carry first: CLC / SEC). |
| Bits | AND ORA EOR | Bitwise on A with a value or memory. |
| Shift | ASL LSR ROL ROR | Shift / rotate A (or memory) one bit. |
| Compare | CMP CPX CPY | Compare a register to a value; sets flags for a branch. |
| Branch | BNE BEQ BCC BCS BMI BPL | Jump only if the last result set that flag. |
| Jump / call | JMP JSR RTS | Unconditional jump; call a subroutine; return from one. |
| Interrupt | SEI CLI RTI BRK | Mask / unmask IRQs; return from / trigger an interrupt (lesson 8). |
| Transfer | TAX TXA TAY TYA TSX TXS | Copy between registers / stack pointer. |
| Flags / misc | CLC SEC PHA PLA NOP | Carry control, push/pull A, do nothing. |
That's not the whole 6502 — it's the part the curriculum uses. The full instruction set is standard 6502; the go6asm project documents the complete assembler.
Directives
.byte $01,$03,$07— emit raw bytes (a table)..wordemits 16-bit values.- That's all you need in CodeLab. The assembler can do much more, but it's kept out of your way here. The one place you reach past this is the interrupts lesson, where you deliberately take over how the chip responds to a hardware signal.
- More about the 6502 — registers, the status flags, how it boots, the 6522 VIA, the memory map.
- How CodeLab is built — the open-source layers, the two CPUs, why it runs at 1 kHz.
- The lessons — the hands-on series, start to finish.
- Standalone CodeLab — the lab on its own, no lesson around it.