Implements an assembler that supports two-pass labels (8-char long only), simplistic macros, and 16-bit constants.
This stage assembles a single source file to a binary output. The stage adds a number of useful helps to avoid any need to hand-calculate addresses and to make forward and backward jumps trivial. In addition, macros allow for usage of a virtual stack, making nested function calls possible.
The first character read from a line determines the behaviour of this assembler:
#
: Comment (ignore text until newline)=abcd
: Defines a 2-byte (16-bit) hex constant:abcdefgh
: Defines an 8-byte global label.abcdefgh
: Defines an 8-byte local label (local to the enclosing global)tab
: Assemble (copy) chars to output until a newlinenewline
: Blank line, skipped@xyz
: Replace with contents of macroxyz
(hardcoded)
If a label (:label___
) or constant (=abcd
) appears in assembled code, it is replaced by the 16-bit constant
that it represents.
The supported macros are:
@ret.
: Return from proc@ret?
: Return from proc if flag@ret^
: Return from proc if not flag@jump
: Jump to address (@jump:label___
)@jmp?
: Jump to address if flag (@jmp?:label___
)@jmp^
: Jump to address if not flag (@jmp^:label___
)@call
: Call address (@call:label___
)@pshN
/@popN
: Push/pop register N to the stack (supports 0-3)
Code blocks are allocated by hand as we only have access to a seek-style (:abcd
) "label". Some small amount
of hand-linking is required for the parsing loops.
See bootstrap1.s
for more details.