Dauug|36 assembly language
The assembly language described in these articles is that of the cross assembler and future self-hosted assembler.
General syntax
All Dauug|36 instructions are documented in these pages, and every instruction’s description includes its syntax. The text below is a redundant summary of the syntax you’ll encounter most frequently.
To first order, Dauug|36 assembly language uses one line of source code per instruction output. Most instructions are ALU instructions that take a destination register, left operand register, right operand register, and use the instruction name as an infix operator. For example:
unsigned d(estination) l(eft operand) r(ight operand) d = l asl r ; Arithmetic Shift Left d = l mix r ; MIX (substitution-permutation network) d = l pat r ; Permute Across Tribbles d = l txor r ; Transposing XOR
Sometimes it’s appropriate to use an infix symbol instead of an operator name. For example:
d = l + r ; A(dd) d = l - r ; S(ubtract) d = l & r ; AND
For some opcodes, both an operator name and symbol are supported:
d = l ^ r ; XOR d = l xor r ; XOR
Sometimes additional symbols are used in addition to the infix symbol:
d = !l | r ; RONL (right or not left) cmp l - r ; compare (set flags as if r is subtracted from l)
Some opcodes only have one operand. These use a symbol or operator name before the operand. Here are two examples that don’t happen to be ALU instructions:
val = ld addr ; load from address in register 'addr' into register 'val' phys = rpt virt ; Read Page Table
Some opcodes only need one register specified. Whether that register is an operand, destination, or both depends on the instruction.
timer setpoint ; 'setpoint' is the left and right operands and destination! jany code_addr ; Jump Anywhere via register
Most of the time when an instruction changes the contents of a register, that register appears to the left of an =
sign. There are a small number of exceptions, such as TIMER
, which internally requires the same register at three points:
setpoint = setpoint timer setpoint ; we don't write it this way timer setpoint ; we write it this way
A few instructions take an immediate value instead of operands:
x = 12345 ; load 12345 directly into register 'x'
Some instructions require a scope or label, indicating where in code memory the next instruction may or will be fetched from. Examples:
jump somewhere.else ; unconditional jump jump < loop ; conditional jump call C_to_F ; call the scope named C_to_F
Some instructions accept only an opcode:
crf ; Clear Range Flag nop ; No OPeration yield ; allow another program to use the CPU
Comments, blank lines, labels, scopes, and register declarations don’t generate any instructions in and of themselves. Here are some examples of how these look:
some_fn:: ; scope ; This single-line comment has a blank line after it. loop: ; label x = 1 ; This is a comment to the end of the line, ( This is a multi-line comment. The name of the unsigned variable below is just 'r', but there is a parenthesized comment to suggest that 'r' is a radius. ) unsigned r(adius) signed x ; This doesn't have to precede 'x' being used.
The preceding 12 lines produce only one instruction, an IMP
(immediate positive) that loads register x
with value 1.
Old assembler
There is a slightly different, more limited language for the old assembler, but both the assembler and old language are nearing obsolescence. Pages 283–287 and 359–366 of the dissertation, in conjunction with the old assembler’s source code and regression tests, are the best source of information about the old assembly language.