Assembler syntax
We assemble with customasm.
Writing a program for the VM
- Always include
../asm/cpu.asmfirst (seeuser/sh.asm). It defines the memory banks so your ROM segment assembles with a base address of0x1000. - When the program is launched, that ROM image is copied into RAM starting at
0x1000and execution begins at your entry label.
Includes
- Always include
asm/cpu.asmto get the core ISA and register definitions. - Optionally include
asm/ext.asmto unlock pseudo-instructions likeINC,JMP addr,CMPI, etc.
#include "../asm/cpu.asm"
#include "../asm/ext.asm" ; optional
Banks and layout
- Kernel: uses
#bank rom(4 KiB at0xE000) for executable code — seekernel/main.asm. - User programs: include
cpu.asmand you automatically get the RAM bank defined there; you typically do not write your own#bankdirectives. #addr <hex>— set the write pointer inside the active bank. Handy to place data at a specific RAM offset.
Example RAM data:
#addr 0x0100 ; place data in general RAM (RAM bank is already active)
SPRITE:
#d8 0b1111_0000
#d8 0b1000_1000
Example ROM code:
#bank rom ; only in the kernel image
start:
LDI R0 0x42
HALT
Data and literals
#d8emits bytes (comma-separated or one-per-line).- Labels mark addresses (
label:). You can jump to labels or use them for data pointers. - Constants use
NAME = value. - Literals: decimal, hex (
0xFF), binary (0b1010_1010), or single-character strings ("A"stores ASCII).
Comments
- Everything after
;on a line is ignored.
Building and running
- Build:
customasm file.asm→ producesfile.bin. - Run:
cargo run -- run file.bin(add--bot other.binto load a bot alongside the judge).