Skip to main content

Module asm

Module asm 

Source
Expand description

A small text assembler.

Mnemonics and operand shapes are read from TABLE rather than from a list kept here, so the two cannot disagree. Adding an instruction to the isa! block makes it assemblable with no change here.

§Syntax

; comments start with ; or #
start:                      ; a label
    addi r1, r0, 10         ; registers are r-13 .. r13
loop:
    addi r1, r1, -1
    br3  r1, loop           ; a label operand becomes a relative offset
    halt

A label used as an immediate resolves to the offset in instructions from the instruction referencing it. See ImmUnit for the units each instruction uses. Operands are separated by commas, whitespace, or both.

§Named constants

.equ NAME, VALUE binds a name to an absolute value. This is the difference between an equate and a label: a label resolves to an offset from the instruction that names it, an equate resolves to the value itself.

.equ CONSOLE_BASE, -19683
    addi r1, r0, CONSOLE_BASE

A name used as an immediate may carry a displacement: BLOCK_WINDOW+1 is one more than the value of BLOCK_WINDOW. Only a single literal offset is accepted; this is not an expression language.

Directives occupy no space in the program. A name may not be both an equate and a label. Device addresses are the main use: a crate that defines a device can emit the matching .equ lines so guest programs and the host agree by construction rather than by a literal copied into both.

§Absolute label references

@label resolves to the tryte address of a label rather than the distance to it. A trap vector needs this, since the handler’s location must not depend on where the instruction naming it happens to sit.

    addi r1, r0, @handler
    csrw r1, TVEC

The address is measured from the base the program is assembled for, which is zero unless assemble_at is given another.

§br3 and its two targets

br3 reaches two targets from one immediate, mirrored about the branch: it adds the immediate when the register is positive and subtracts it when the register is negative. Two forms are accepted.

br3 rs1, label              ; label is the POSITIVE target
br3 rs1, neg_lbl, pos_lbl   ; both named; the assembler checks the mirror

The one-label form suits a loop, where the label is behind the branch and only the positive case is reachable. The two-label form suits dispatch on Opcode::Cmp3, and fails at assembly time if the targets are not mirrored rather than branching the wrong way at runtime.

Where the targets cannot be mirrored, use brn and brp, which take one target each over the full immediate range.

Structs§

AsmError
What went wrong, and where.
Program
An assembled program.

Enums§

AsmErrorKind
The kinds of assembly failure.

Functions§

assemble
Assembles source text.
assemble_at
Assembles source that will be loaded at tryte address base.
disassemble
Disassembles a run of instructions, one per line, with indices.