The CPU will begin execution at address 0
. There is no special ‘main’ label - the first thing
you write will be the first thing executed.
Instructions and registers are case-insensitive.
Both decimal and ternary are supported with no prefix.
Use a semicolon ;
to ignore everything following it on that line.
Use .label
on its own line to define a label, which represents the address of the instruction or
value following the label.
To use a label’s address as an operand, just write its name. You can also write .label[offset]
.
.main
JAL .load200
; ...
.load200
MOV a0, 200
JMP ra
You can declare a place for a single tryte of data by putting $name
on its own line.
$name[n]
declares n
trytes of data and can be accessed with $name[offset]
.
Data is placed at exactly the position it appears in the sourcecode. Make sure you JMP past any data declarations to avoid running data as code.
$player_position[2]
.get_player_pos
LDA r0, $player_position[0] ; x
LDA r1, $player_position[1] ; y
JMP ra
Memory-mapped symbols are made available with this syntax also.
Syntax | Description |
---|---|
NOP |
Does nothing |
PSH x, y, z, ... |
Pushes the given registers to the stack |
POP x, y, z, ... |
Pops the given registers from the stack in reverse order |
This is just a suggestion - there is no obligation to follow it in your code.
Unlike MIPS, subroutines have no obligation to PSH registers they mutate. If you
want a register’s value saved, PSH it before calling and POP afterwards.
However, remember that if a subroutine is calling into another it must PSH ra
and POP ra
.
Input and ouput should be done through the rX registers, sequentially. It is
useful to write a function signature like a, b -> c, d
to represent the
inputs r0
“a” / r1
“b” and the outputs r0
“c” / r1
“d”.
MOV r0, 1
MOV r1, 2
JAL .sum2
; a, b -> sum
.sum2
ADD r0, r1
MOV r0, r2
JMP ra