Skip to content

Instructions overview

Duart Snel edited this page Jul 28, 2021 · 9 revisions

Where am i?

This page lays some of the fundamentals in place that will be used in the documentations. Helpers are used to make reading (and constructing) the documentation easier as writing and explaining only numbers is not very "sustainable". It's important that you understand what these helper methods do BEFORE reading the documentation or attempting to make a higher level language.

The builder and its methods

The builder (IDG Builder) is an early attempt at making the writing of our custom assembly code easier by wrapping them into javascript methods that would not only write the code but also keeps track of where to put the assembly code IDs and how much memory is needed for the instruction set to function properly. The builder in itself is not important but it's a couple of methods that it exposes that will make writing documentation and tests much easier, here they are:

  • insert8()
  • insert16()
  • insert32()
  • _regKeyToIndex()

before i explain the insert instructions in detail, the _regKeyToIndex method simply takes a string that represents a register (a storage location) and translates this into it's corresponding register index (number) that is used while the machine interprets and executes instructions. it looks something like this:

public _regKeyToIndex(x: RegisterKey) {
    return RegisterIndexOf[x] * 4; // multiplication by 4 due to every register taking 32-bits of space (4 bytes)
}

_regKeyToIndex("r1"); // gives the index of the register "r1"

Insert instructions

The insert instructions:

  • insert8()
  • insert16()
  • insert32()

Helps us align a number into memory, it takes care of breaking up insertions that are larger than 8-bits into sections of 8-bits. It also takes care of moving the cursor (or instruction pointer) by a certain amount depending on how much is to be inserted (e.g. 8-bits = 1 byte so increment the cursor by one, 32-bits = 4 bytes so increment the cursor by 4).

Why is this needed? think of a Turing machine where you have one continuous set of tape, only in this case you are able to go and modify this tape at any point in time, now ask yourself this: what happens when you modify the first symbol on the tape and you want to add another symbol but instead of adding one you forget to move to the next section of the tape? (hint: it replaces the original symbol).

Here's a diagram showing how these methods work.

Sub-instructions

In the above diagram you also see that the ADD instruction takes in another 8bit value right after that indicates the sub-instruction. this allows the main 8-bit instruction "box" to stay uncluttered as we combine similar instructions with the same amount of parameters together in one. Here's the enum representing the sub-instructions for the ADD instruction.

export enum additionType {
  ADD_REG_REG,
  ADD_LIT_REG,
  ADD_REG_LIT,
  ADD_LIT_MEM,
  ADD_REG_MEM,
  ADD_LIT_LIT,
  ADD_MEM_MEM,
}

Note on naming convention

Usually the instructions follow a naming pattern like so

<name>_<loc>_<loc> ...

where name is just a descriptive name typically representing what the instruction will do and loc is indicating where the value is to be fetched from.

REG -> Register (fetch a register value and operate with it, supplied is the register index)
MEM -> Memory (fetch the value in memory, supplied is then the memory address)
LIT -> Literal (the value that is supplied is the one that is used)