Basic Syntax¶
Registers¶
Most instructions will require you to interact with the processor’s registers. The CorvusPrudensUnit features eight 16-bit registers – from a to h.
Instructions¶
Corvassembly borrows many syntactical elements from typical assembly implementations. Code consists of instructions followed by comma-separated arguments:
add a, 42
For most arithmetic and memory operations, the first argument indicates which CPU register the instruction should operate on. The second argument can either be an immediate value, another register, or an address in RAM represented by a variable. An optional third argument indicates which register to store the result in. By default, the result is stored in the register of argument 1.
Labels¶
Labels are written as names followd by a colon:
main:
// main code loop
jmp main
and can be used as arguments for jump-type instructions. If you’d like to attach an interrupt to a label, append the name of the desired interrupt to the label in parentheses:
frameInterrupt(FRAME):
// interrupt routine
rti FRAME
If you wish to preserve the state of the registers (which you almost
always will), you must end the interrupt subroutine with an rti
instruction followed by the name of the interrupt.
Conditional Instructions¶
Instructions with conditional execution require conditions as arguments. For example, a conditional jump is formatted as:
joc equal, label
The six processor conditions are zero
, carry
, negative
, equal
,
greater
, and less
. The first three are updated by most arithmetic and
logic instructions, and the last three are updated by the cmp
instruction.
Variables¶
Variables are handled by the assembler with little user intervention.
Align directives or other similar manual adjustment are not currently supported.
The two main types of variables are ram
variables and rom
variables. ram
variables cannot be given initial assignments, while rom variables must be
given assignments:
ram ramVar
rom romVar = 42
If you want to parameterize your code, you can also use pre
variables. These
pre-processor values are not stored in memory once the code is assembled:
pre INIT = 42
rom romVar = INIT
Comments¶
Single line comments are indicated by two forward-slashes. Block comments can be made with /* and */:
// this is an in-line comment!
/*
This is a multi-
line comment!
*/
Putting it all together¶
Using just these basic features, you can of course construct any program imaginable (though it may not be very manageable). Here’s an example of computing the Fibonacci sequence and sending it to a memory-mapped UART:
// Fibonacci sequence!
pre LIMIT = 255
reset:
ldr a, 1
ldr b, 0
ldr c, 0
fibLoop:
str a, UART // writing to a memory-mapped UART module
add a, 0, c // like a mov a, c instruction
add a, b
add c, 0, b
cmp a, LIMIT
joc greater, reset
jmp fibLoop