Assembler reference
Dialect declaration
To use the assembler mode start your file with the following line:
(mod asm)
Imports
To import functions from another module use the use statement:
(use module-name)
Static variables
Static variables are variables that are directly stored inside the binary.
The assembler supports static variables of the following types:
int(64-bit)uint(64-bit)float(64-bit)strbuffer(zero-initialized)
str
Static strings (str) consist of a uint representing the size of the string
in bytes followed by the bytes of the string terminated by a zero-byte.
Strings are aligned to 4 bytes by appending zero-bytes to the end.
Referencing a string returns the address to the bytes of the string.
Syntax
Static variables are declared like this:
(static a 10) ; int
(static b 10u) ; uint
(static c 10.0) ; float
(static d "A string") ; str
(static e (buffer 1024u)) ; buffer of size 1024
Labels
Labels are like functions though they do not have a signature and may interact with the state of the runtime in any way possible.
Labels may be public (+label) or private (-label).
Public modules can be accessed by other modules while private modules can only be accessed from the module they were declared in.
Syntax
A label is declared like this:
(+label add (do
(add r0 r0 r1)
))
Control flow
The assembler does conditional code execution through control flow statements.
do
The do statement executes multiple instructions after one another.
It looks like this:
(+label exit-failure (do
(mov r0 1u)
(int 4u)
(crash)
))
if
The if statement executes code conditionally.
It takes one of the possible conditions (=, !=, <, >, <=, >=, =0,
!0), a register with the source, and code to execute.
It can be used like this:
(+label abs (do
(mov r1 0u)
(cmps r1 r0 r1)
(if >= r1 (ret))
(mov r1 0u)
(sub r0 r1 r0)
))
Here it is used with the early return pattern.
while
The while statement executes code while a certain condition is met.
It has a syntax similar to the one of an if statement:
(+label factorial (do
(mov r1 1u)
(while !0 r0 (do
(mul r1 r0 r1)
(sub r0 r0 1u)
))
(mov r0 r1)
))
do-while
Alternatively to the while loop you can use a do-while loop.
The difference is that for the do-while loop the first iteration is executed
always.
Additionally the syntax is a bit different:
(+label test (do
; ...
(do-while (do
; ...
) !0 r0)
; ...
))
Instructions
add Xdst Xlhs u17- Add
u17toXlhsand store the result inXdst - Supports signed and unsigned integers
- Add
add Xdst Xlhs Xrhs- Add
XrhstoXlhsand store the result inXdst - Supports signed and unsigned integers
- Add
sub Xdst Xlhs u17- Subtract
u17fromXlhsand store the result inXdst - Supports signed and unsigned integers
- Subtract
sub Xdst Xlhs Xrhs- Subtract
XrhsfromXlhsand store the result inXdst - Supports signed and unsigned integers
- Subtract
mul Xdst Xlhs u17- Multiply
Xlhsbyu17and store the result inXdst - Supports signed and unsigned integers
- Multiply
mul Xdst Xlhs Xrhs- Multiply
XlhsbyXrhsand store the result inXdst - Supports signed and unsigned integers
- Multiply
div Xdst Xlhs u17- Divide
Xlhsbyu17and store the result inXdst - Supports unsigned integers only
- Divide
div Xdst Xlhs Xrhs- Divide
XlhsbyXrhsand store the result inXdst - Supports unsigned integers only
- Divide
rem Xdst Xlhs u17- Store the remainder of
Xlhsandu17inXdst - Supports unsigned integers only
- Store the remainder of
rem Xdst Xlhs Xrhs- Store the remainder of
XlhsandXrhsinXdst - Supports unsigned integers only
- Store the remainder of
divs Xdst Xlhs i17- Divide
Xlhsbyi17and store the result inXdst - Supports signed integers only
- Divide
divs Xdst Xlhs Xrhs- Divide
XlhsbyXrhsand store the result inXdst - Supports signed integers only
- Divide
rems Xdst Xlhs i17- Store the remainder of
Xlhsandi17inXdst - Supports signed integers only
- Store the remainder of
rems Xdst Xlhs Xrhs- Store the remainder of
XlhsandXrhsinXdst - Supports signed integers only
- Store the remainder of
mov Xdst u22- Move
u22intoXdst
- Move
mov Xdst Xsrc- Move
XsrcintoXdst
- Move
movs Xdst i22- Move
i22intoXdstwith sign extension
- Move
shl Xdst Xlhs u11- Move
Xlhsshifted left byu11intoXdst
- Move
shl Xdst Xlhs Xrhs- Move
Xlhsshifted left byXrhsintoXdst
- Move
shr Xdst Xlhs u11- Move
Xlhsshifted right byu11intoXdst
- Move
shr Xdst Xlhs Xrhs- Move
Xlhsshifted right byXrhsintoXdst
- Move
shrs Xdst Xlhs u11- Move
Xlhsarithmetically shifted right byu11intoXdst
- Move
shrs Xdst Xlhs Xrhs- Move
Xlhsarithmetically shifted right byXrhsintoXdst
- Move
ldrb Xdst Xsrc i11- Load 8 bits from address
Xsrcwith offseti11intoXdst
- Load 8 bits from address
ldrh Xdst Xsrc i11- Load 16 bits from address
Xsrcwith offseti11intoXdst
- Load 16 bits from address
ldrw Xdst Xsrc i11- Load 32 bits from address
Xsrcwith offseti11intoXdst
- Load 32 bits from address
ldr Xdst Xsrc i11- Load 64 bits from address
Xsrcwith offseti11intoXdst
- Load 64 bits from address
strb Xdst Xsrc i11- Store 8 bits from
Xsrcto addressXdstwith offseti11
- Store 8 bits from
strh Xdst Xsrc i11- Store 16 bits from
Xsrcto addressXdstwith offseti11
- Store 16 bits from
strw Xdst Xsrc i11- Store 32 bits from
Xsrcto addressXdstwith offseti11
- Store 32 bits from
str Xdst Xsrc i11- Store 64 bits from
Xsrcto addressXdstwith offseti11
- Store 64 bits from
int 16u- Interrupt the runtime with code
u16
- Interrupt the runtime with code
ncall u21- Call a native function with id
u21
- Call a native function with id
ncall Xid- Call a native function with id
Xid
- Call a native function with id
vcall u21- Call a virtual function with id
u21
- Call a virtual function with id
vcall Xid- Call a virtual function with id
Xid
- Call a virtual function with id
addf Xdst Xlhs Xrhs- Add the float
Xrhsto the floatXlhsand store the result inXdst
- Add the float
subf Xdst Xlhs Xrhs- Subtract the float
Xrhsfrom the floatXlhsand store the result inXdst
- Subtract the float
mulf Xdst Xlhs Xrhs- Multiply the float
Xrhsby the floatXlhsand store the result inXdst
- Multiply the float
divf Xdst Xlhs Xrhs- Divide the float
Xrhsby the floatXlhsand store the result inXdst
- Divide the float
and Xdst Xlhs Xrhs- Move
Xlhs&XrhsintoXdst(bitwise and)
- Move
or Xdst Xlhs Xrhs- Move
Xlhs|XrhsintoXdst(bitwise or)
- Move
xor Xdst Xlhs Xrhs- Move
Xlhs^XrhsintoXdst(bitwise xor)
- Move
cmp Xdst Xlhs Xrhs- Compare
XlhsandXrhsand store the result inXdst - Supports unsigned integers only
- Compare
cmps Xdst Xlhs Xrhs- Compare
XlhsandXrhsand store the result inXdst - Supports signed integers only
- Compare
cmpf Xdst Xlhs Xrhs- Compare the float
Xlhsand the floatXrhsand store the result inXdst
- Compare the float
not Xdst Xsrc- Move !
XsrcintoXdst(bitwise not)
- Move !
fti Xdst Xsrc- Move the float
Xsrcconverted to an integer intoXdst
- Move the float
itf Xdst Xsrc- Move the integer
Xsrcconverted to a float intoXdst
- Move the integer
ldbo Xdst- Load the address of the first byte after the binary header into
Xdst
- Load the address of the first byte after the binary header into
ldpc Xdst- Load the program counter into
Xdst
- Load the program counter into
zero Xdst- Move zero into
Xdst
- Move zero into
dbg Xreg- Debug print the integer
Xreg
- Debug print the integer
inc Xreg- Increment the integer
Xreg
- Increment the integer
nop- Do nothing
halt- Halt the runtime
ret- Return from a call
crash- Insert an invalid opcode and crash the runtime dumping the register contents
ref Xdst <static variable>orlea Xdst <static variable>- Load the effective address of a static variable into
Xdst
- Load the effective address of a static variable into