Website Summary Files Commits Branches @commit @diff @stats
path: root / assembler
NameSize
..
Cargo.toml133 Blog stats plain blame
README.md4.5 KiBlog stats plain blame
src100 Blog stats plain

tonkobali assembler

This is a very limited assembler. Since we support only a single instruction (SUBLEQ), the assembler can also take in "higher-level" instructions which are then simplified (an operation which I call in the codebase as "collapse") to SUBLEQ.

The main goal is to use these higher-order instructions, not subleq itself. Look at the examples directory for examples.

Text format

There are two types of lines in your source file: instruction calls and variable definitions. Blank lines are allowed.

Instruction calls

label: instruction arg1, arg2, ... ; Comment until the end of the line

Labels and comments are optional. A label is a name, refer to names for allowed characters.

You may separate a label and it's instruction by a newline and blank lines. You may issue multiple labels one after another, but only when separated by at least one newline (meaning you may not define two labels on the same line).

Instruction must be separated from their first argument with a blank (space or tab). Capitalisation is not ignored.

Arguments are values, with minor type limitations in certain higher-order instructions. They are seprated by commas with arbitrary amount of blank (space or tab) characters around the commas. All arguments must be on the same line as their instruction.

Variable definitions

name = value ; Comment until the end of the line

Comments are optional.

Names

A name is a sequence of ASCII letters (capital and lowercase), numbers, underscore, dot, $ and ?. Capitalization is not ignored.

There is no scoping of names, or in other words, every name is global. Labels are also names.

Repeat names overwrite previous ones globally, meaning no matter where two definitions are, the second will override the first everywhere in your program.

Values

All values are reduced to addresses in the memory (after all, all SUBLEQ arguments are addresses). We distinguish between three "types" of values:

  • Absolute addresses, these are addresses in the memory and are passed down as-is

They are defined as unsigned numbers, prepended with the % symbol. For example: %384.

  • Number constants, they're placed somewhere in memory and their address is passed

They are signed 64-bit numbers (as is the Word type for our VM). For example: 56, -912.

  • Strings, they're converted into a sequence of numbers, each being the decimal ASCII representation of the character, ending with a zero. The address of the first "ltter" is passed

They are a sequence of characters, surrounded by double quotes. Double quotes and backwards slash can be escaped by prepending a backwards slash. For example: "Hello World", "He said \"Wow\"", "C:\\System".

Higher-order instructions

Instruction Description Argument 1 Argument 2
jmp Jump to address Location to jump to
inc Increment value Location of value
dec Decrement value Location of value
add Add the first value to the second and store the result in the second First value Second value
sub Subtract the first value to the second and store the result in the second First value Second value
mov Move (copy) the value from the first address to the second address First location Second location
beq Branch if first value is equal to zero Value to check Location to jump to
jsr Jump to subroutine Location to jump to
rts Return from subroutine

The idea of subroutines is that jumping to one is the same as normal jump, however the address after the jump is stored. So, returning from a subroutine allows you to jump back after the location you entered the subroutine from. Addresses are stored in the memory via a "stack", in the first 1024 addresses.