Assembly

Assembly code provides a way to specify instructions for the computer to perform in a more human readable from than machine code

Assembly operations and arguments to specify their behaviour can be saved in an assembly file and passed to an assembler to convert them to machine code that the computer can then execute.

These are the operations and other assembly constructs that can be used to create a valid assembly file.

Arithmetic Operations

ADD

The ADD operation adds the value held in the specified module (or a constant) to the accumulator. The ALU flags generated by this operation are stored.

The possible usages are:

  • ADD A
  • ADD B
  • ADD C
  • ADD CONST

ADDC

The ADDC operation adds the value held in the specified module (or a constant) to the accumulator. If the carry flag is high, an additional 1 is added. The ALU flags generated by this operation are stored.

The possible usages are:

  • ADDC A
  • ADDC B
  • ADDC C
  • ADDC CONST

SUB

The SUB operation subtracts the value held in the specified module (or a constant) from the accumulator. The ALU flags generated by this operation are stored.

The possible usages are:

  • SUB A
  • SUB B
  • SUB C
  • SUB CONST

SUBB

The SUBB operation subtracts the value held in the specified module (or a constant) from the accumulator. If the borrow flag is high an additional 1 is subtracted. The ALU flags generated by this operation are stored.

The possible usages are:

  • SUBB A
  • SUBB B
  • SUBB C
  • SUBB CONST

LSHIFT

The LSHIFT operation moves all the bits in the specified module one place to the left (toward the most significant bit) in place. A zero is added in the rightmost (least significant bit) place. The ALU flags generated by this operation are stored.

The possible usages are:

  • LSHIFT ACC
  • LSHIFT A
  • LSHIFT B
  • LSHIFT C

LSHIFTC

The LSHIFTC operation moves all the bits in the specified module one place to the left (toward the most significant bit) in place. If the carry flag is high, a 1 is added in the rightmost (least significant bit) place. If the flag is low, the rightmost place is left as 0. The ALU flags generated by this operation are stored.

The possible usages are:

  • LSHIFT ACC
  • LSHIFT A
  • LSHIFT B
  • LSHIFT C

INCR

The INCR operation adds one to the given argument (in place). The ALU flags generated by this operation are stored.

The possible usages are:

  • INCR ACC
  • INCR A
  • INCR B
  • INCR C

DECR

The DECR operation subracts one from the given argument (in place). The ALU flags generated by this operation are stored.

The possible usages are:

  • DECR ACC
  • DECR A
  • DECR B
  • DECR C

Data Operations

COPY

The COPY operation copies the value from a source module to a destination module. This overwrites the current value of the destination register. It requires a single machine code byte in program memory.

It is used by specifying the source module as the first argument and the destination module as the second.

The possible usages are:

  • COPY ACC A
  • COPY ACC B
  • COPY ACC C
  • COPY ACC SP
  • COPY A ACC
  • COPY A B
  • COPY A C
  • COPY A SP
  • COPY B ACC
  • COPY B A
  • COPY B C
  • COPY B SP
  • COPY C ACC
  • COPY C A
  • COPY C B
  • COPY C SP
  • COPY PC ACC
  • COPY PC A
  • COPY PC B
  • COPY PC C
  • COPY PC SP
  • COPY SP ACC
  • COPY SP A
  • COPY SP B
  • COPY SP C

LOAD

The LOAD operation loads a value from data memory into a module.

It is used by specifying the position in memory as the first argument and the destination module as the second. The position in memory can be a module or a constant and is encased in square parentheses.

The possible usages are:

  • LOAD [ACC] ACC
  • LOAD [ACC] A
  • LOAD [ACC] B
  • LOAD [ACC] C
  • LOAD [A] ACC
  • LOAD [A] A
  • LOAD [A] B
  • LOAD [A] C
  • LOAD [B] ACC
  • LOAD [B] A
  • LOAD [B] B
  • LOAD [B] C
  • LOAD [C] ACC
  • LOAD [C] A
  • LOAD [C] B
  • LOAD [C] C
  • LOAD [PC] ACC
  • LOAD [PC] A
  • LOAD [PC] B
  • LOAD [PC] C
  • LOAD [SP] ACC
  • LOAD [SP] A
  • LOAD [SP] B
  • LOAD [SP] C
  • LOAD [CONST] ACC
  • LOAD [CONST] A
  • LOAD [CONST] B
  • LOAD [CONST] C

STORE

The STORE operation stores a value from a module in memory.

It is used by specifying the module as the first argument and the location in memory as the second. The location in memory can be a module or a constant and is encased in square parentheses.

The possible usages are:

  • STORE ACC [ACC]
  • STORE ACC [A]
  • STORE ACC [B]
  • STORE ACC [C]
  • STORE ACC [PC]
  • STORE ACC [SP]
  • STORE ACC [CONST]
  • STORE A [ACC]
  • STORE A [A]
  • STORE A [B]
  • STORE A [C]
  • STORE A [PC]
  • STORE A [SP]
  • STORE A [CONST]
  • STORE B [ACC]
  • STORE B [A]
  • STORE B [B]
  • STORE B [C]
  • STORE B [PC]
  • STORE B [SP]
  • STORE B [CONST]
  • STORE C [ACC]
  • STORE C [A]
  • STORE C [B]
  • STORE C [C]
  • STORE C [PC]
  • STORE C [SP]
  • STORE C [CONST]
  • STORE PC [ACC]
  • STORE PC [A]
  • STORE PC [B]
  • STORE PC [C]
  • STORE PC [PC]
  • STORE PC [SP]
  • STORE PC [CONST]

PROGLOAD

The PROGLOAD operation loads a value from program memory into the ACC module.

It is used by specifying the position in program memory as the single argument. The position in memory can be a module or a constant and is encased in square parentheses.

The possible usages are:

  • PROGLOAD [ACC]
  • PROGLOAD [A]
  • PROGLOAD [B]
  • PROGLOAD [C]
  • PROGLOAD [PC]
  • PROGLOAD [SP]
  • PROGLOAD [CONST]

PROGSTORE

The PROGSTORE operation stores the value in the ACC module into program memory.

It is used by specifying the position in program memory as the single argument. The position in memory can be a module or a constant and is encased in square parentheses.

The possible usages are:

  • PROGSTORE [ACC]
  • PROGSTORE [A]
  • PROGSTORE [B]
  • PROGSTORE [C]
  • PROGSTORE [PC]
  • PROGSTORE [SP]
  • PROGSTORE [CONST]

PUSH

The PUSH operation takes a value in a module and add it to the top of the stack.

The stack grows downwards in memory, starting at address 255. The SP module is used to keep track of the top of the stack. The value in SP points at the current top of the stack. SP should be initialised to 0 so that the first push will put the value at address 255. The push first decrements SP, then stores the value in memory at the new value of SP.

The flags generated while decrementing SP are not stored.

The push operation is used by specifying the module to push onto the stack as the first and only argument.

The possible usages are:

  • PUSH ACC
  • PUSH A
  • PUSH B
  • PUSH C
  • PUSH PC

POP

The POP operation takes the value from the top of the stack and copies it to a module.

The value currently at top of the stack is pointed to by SP. A pop will first copy the value at the top of the stack into a module, then increment SP (the stack grows downwards in memory from address 255).

The flags generated while incrementing SP are not stored.

The pop is used by specifying the module to pop the value off the stack into as the first and only argument.

The possible usages are:

  • POP ACC
  • POP A
  • POP B
  • POP C

SET

The SET operation will set a module in the computer to a given constant value.

It is used by specifying a module as the first argument, then the value to set it to as a constant.

It requires two machine code bytes in program memory. Consider the SET_ZERO operation if the constant is zero.

The possible usages are:

  • SET ACC CONST
  • SET A CONST
  • SET B CONST
  • SET C CONST
  • SET SP CONST

SET_ZERO

The SET_ZERO operation will set a module in the computer to zero.

The ALU flags generated by this operation are not stored.

It is used by specifying a module as the first and only argument.

The possible usages are:

  • SET_ZERO ACC
  • SET_ZERO A
  • SET_ZERO B
  • SET_ZERO C

Program Control Operations

NOOP

The NOOP does nothing - no module transfers occur on the bus for one instruction cycle.

The possible usages are:

  • NOOP

JUMP

The JUMP operation will set the program counter to a value.

The possible usages are:

  • JUMP ACC
  • JUMP A
  • JUMP B
  • JUMP C
  • JUMP SP
  • JUMP CONST
  • JUMP [ACC]
  • JUMP [A]
  • JUMP [B]
  • JUMP [C]
  • JUMP [SP]
  • JUMP [PC]
  • JUMP [CONST]

JUMP_IF_LT_ACC

The JUMP_IF_LT_ACC operation will set the program counter (jump) to the value of a given constant (second argument) if the value of the first argument (module or constant) is less than the accumulator.

The instruction generates and stores (clobbers) the ALU flags.

The possible usages are:

  • JUMP_IF_LT_ACC A CONST
  • JUMP_IF_LT_ACC B CONST
  • JUMP_IF_LT_ACC C CONST
  • JUMP_IF_LT_ACC PC CONST
  • JUMP_IF_LT_ACC SP CONST
  • JUMP_IF_LT_ACC CONST CONST

JUMP_IF_LTE_ACC

The JUMP_IF_LTE_ACC operation will set the program counter (jump) to the value of a given constant (second argument) if the value of the first argument (module or constant) is less than or equal to the accumulator.

The instruction generates and stores (clobbers) the ALU flags.

The possible usages are:

  • JUMP_IF_LTE_ACC A CONST
  • JUMP_IF_LTE_ACC B CONST
  • JUMP_IF_LTE_ACC C CONST
  • JUMP_IF_LTE_ACC PC CONST
  • JUMP_IF_LTE_ACC SP CONST
  • JUMP_IF_LTE_ACC CONST CONST

JUMP_IF_EQ_ACC

The JUMP_IF_EQ_ACC operation will set the program counter (jump) to the value of a given constant (second argument) if the value of the first argument (module or constant) is equal to the accumulator.

The instruction generates and stores (clobbers) the ALU flags.

The possible usages are:

  • JUMP_IF_EQ_ACC A CONST
  • JUMP_IF_EQ_ACC B CONST
  • JUMP_IF_EQ_ACC C CONST
  • JUMP_IF_EQ_ACC PC CONST
  • JUMP_IF_EQ_ACC SP CONST
  • JUMP_IF_EQ_ACC CONST CONST

JUMP_IF_GTE_ACC

The JUMP_IF_GTE_ACC operation will set the program counter (jump) to the value of a given constant (second argument) if the value of the first argument (module or constant) is greater than or equal to the accumulator.

The instruction generates and stores (clobbers) the ALU flags.

The possible usages are:

  • JUMP_IF_GTE_ACC A CONST
  • JUMP_IF_GTE_ACC B CONST
  • JUMP_IF_GTE_ACC C CONST
  • JUMP_IF_GTE_ACC PC CONST
  • JUMP_IF_GTE_ACC SP CONST
  • JUMP_IF_GTE_ACC CONST CONST

JUMP_IF_GT_ACC

The JUMP_IF_GT_ACC operation will set the program counter (jump) to the value of a given constant (second argument) if the value of the first argument (module or constant) is greater than the accumulator.

The instruction generates and stores (clobbers) the ALU flags.

The possible usages are:

  • JUMP_IF_GT_ACC A CONST
  • JUMP_IF_GT_ACC B CONST
  • JUMP_IF_GT_ACC C CONST
  • JUMP_IF_GT_ACC PC CONST
  • JUMP_IF_GT_ACC SP CONST
  • JUMP_IF_GT_ACC CONST CONST

JUMP_IF_EQ_ZERO

The JUMP_IF_EQ_ZERO operation will set the program counter (jump) to the value of a given constant (second argument) if the value of the first argument (a module) is equal to zero.

The instruction generates and stores (clobbers) the ALU flags.

The possible usages are:

  • JUMP_IF_EQ_ZERO ACC CONST
  • JUMP_IF_EQ_ZERO A CONST
  • JUMP_IF_EQ_ZERO B CONST
  • JUMP_IF_EQ_ZERO C CONST
  • JUMP_IF_EQ_ZERO PC CONST
  • JUMP_IF_EQ_ZERO SP CONST

JUMP_IF_POSITIVE_FLAG

The JUMP_IF_POSITIVE_FLAG operation will set the program counter to the value of a given constant if the last operation that the ALU flags were stored for resulted in a positive value (when read as 2’s compliment).

The possible usages are:

  • JUMP_IF_POSITIVE_FLAG CONST

JUMP_IF_NEGATIVE_FLAG

The JUMP_IF_NEGATIVE_FLAG operation will set the program counter to the value of a given constant if the last operation that the ALU flags were stored for resulted in a negative value (when read as 2’s compliment).

The possible usages are:

  • JUMP_IF_NEGATIVE_FLAG CONST

JUMP_IF_OVERFLOW_FLAG

The JUMP_IF_OVERFLOW_FLAG operation will set the program counter to the value of a given constant if the last operation that the ALU flags were stored for resulted in an overflow.

The possible usages are:

  • JUMP_IF_OVERFLOW_FLAG CONST

JUMP_IF_NOT_OVERFLOW_FLAG

The JUMP_IF_OVERFLOW_FLAG operation will set the program counter to the value of a given constant if the last operation that the ALU flags were stored for did not result in an overflow.

The possible usages are:

  • JUMP_IF_NOT_OVERFLOW_FLAG CONST

JUMP_IF_UNDERFLOW_FLAG

The JUMP_IF_UNDERFLOW_FLAG operation will set the program counter to the value of a given constant if the last operation that the ALU flags were stored for resulted in an underflow.

The possible usages are:

  • JUMP_IF_UNDERFLOW_FLAG CONST

JUMP_IF_NOT_UNDERFLOW_FLAG

The JUMP_IF_NOT_UNDERFLOW_FLAG operation will set the program counter to the value of a given constant if the last operation that the ALU flags were stored for did not result in an underflow.

The possible usages are:

  • JUMP_IF_NOT_UNDERFLOW_FLAG CONST

JUMP_IF_ZERO_FLAG

The JUMP_IF_ZERO_FLAG operation will set the program counter to the value of a given constant if the last operation that the ALU flags were stored for resulted in an answer of zero.

The possible usages are:

  • JUMP_IF_ZERO_FLAG CONST

JUMP_IF_NOT_ZERO_FLAG

The JUMP_IF_NOT_ZERO_FLAG operation will set the program counter to the value of a given constant if the last operation that the ALU flags were stored for resulted in a non zero answer.

The possible usages are:

  • JUMP_IF_NOT_ZERO_FLAG CONST

CALL

The CALL operation will push the current program counter (i.e. the next instruction to be executed) onto the stack, then set the program counter ( i.e. jump) to the value in the given module or constant.

The possible usages are:

  • CALL ACC
  • CALL A
  • CALL B
  • CALL C
  • CALL CONST

RETURN

The RETURN operation will pop the top of the stack into the program counter.

It expects to be used after having arrived at a section of assembly with the CALL instruction.

The possible usages are:

  • RETURN

HALT

The HALT operation halts execution of the computer by stopping the clock.

The possible usages are:

  • HALT

Logical Operations

NOT

The NOT operation inverts all the bits of the specified module in place. The ALU flags generated by this operation are stored.

The possible usages are:

  • NOT ACC
  • NOT A
  • NOT B
  • NOT C

AND

The AND operation performs a logical AND with the value held in the specified module (or a constant) and the accumulator. The result is stored in the accumulator. The ALU flags generated by this operation are stored.

The possible usages are:

  • AND A
  • AND B
  • AND C
  • AND CONST

NAND

The NAND operation performs a logical NAND with the value held in the specified module (or a constant) and the accumulator. The result is stored in the accumulator. The ALU flags generated by this operation are stored.

The possible usages are:

  • NAND A
  • NAND B
  • NAND C
  • NAND CONST

OR

The OR operation performs a logical OR with the value held in the specified module (or a constant) and the accumulator. The result is stored in the accumulator. The ALU flags generated by this operation are stored.

The possible usages are:

  • OR A
  • OR B
  • OR C
  • OR CONST

NOR

The NOR operation performs a logical NOR with the value held in the specified module (or a constant) and the accumulator. The result is stored in the accumulator. The ALU flags generated by this operation are stored.

The possible usages are:

  • NOR A
  • NOR B
  • NOR C
  • NOR CONST

XOR

The XOR operation performs a logical XOR with the value held in the specified module (or a constant) and the accumulator. The result is stored in the accumulator. The ALU flags generated by this operation are stored.

The possible usages are:

  • XOR A
  • XOR B
  • XOR C
  • XOR CONST

NXOR

The NXOR operation performs a logical NXOR (an XOR, then inverted) with the value held in the specified module (or a constant) and the accumulator. The result is stored in the accumulator. The ALU flags generated by this operation are stored.

The possible usages are:

  • NXOR A
  • NXOR B
  • NXOR C
  • NXOR CONST

Miscellaneous Operations

ROT_LEFT

The ROT_LEFT operation moves all the bits in the number one place to the left (most significant side), adding a 0 on the least significant side. If the most significant bit was a 1, then after the rotation this is set back on the least significant side.

This operation will generate and store (clobber) ALU flags.

The possible usages are:

  • ROT_LEFT ACC
  • ROT_LEFT A
  • ROT_LEFT B
  • ROT_LEFT C

Constants

Constants are values that the assembler will convert to machine code bytes for operations that require data in the machine code. For example, a jump to an explicit index in program memory, or setting a register to an explicit value.

There are 3 kinds of constants: labels, variables and numbers.

Labels

A label binds to the line of assembly that follows it. Once assembly is complete the label’s value is the index in program memory of the instruction byte that followed the label definition. E.g. If an assembly file looked like this:

    LOAD [#123] A
    ADD A

@label
    SET B #42

The value of @label would be 3. The instruction byte corresponding to SET B #42 is at program memory index 3. LOAD [#123] A takes 2 bytes, ADD A one, and SET B #42 is the byte after that.

Labels are typically used by jump operations.

A label is a token that starts with the @ character followed by any letter or an underscore, then any alphanumeric or an underscore. E.g.:

  • @label
  • @label_1
  • @_other_label

Labels must be unique.

A label is defined by putting it on a line by itself.

Variables

Variables are named aliases for indexes into data memory. They can be predeclared by putting them by themselves on a line or declared as they are used by using them as an argument.

The index for a given variable is determined by the assembler. As it parses assembly lines from the start of the file to the end, addresses are assigned to variables as they are encountered in the file. E.g. for the following assembly:

$variable1
COPY A ACC
LOAD [$variable2] A

variable1 is predeclared, variable2 is declared as it’s used. Once assembled, variable1 is an alias for 0, variable2 is an alias for 1.

A variable is a token that starts with the $ character followed by any letter or an underscore, then any alphanumeric or an underscore. E.g.:

  • $variable
  • $variable1
  • $_other_variable

Numbers

Numbers are integer values. In most cases they within the range -127 to 255 (inclusive). This range comes from the minimum and maximum values that 8 bits, or 8 bits with 2’s compliment encoding can hold.

A number is a token that starts with the # character and is followed by any valid Python integer definition. E.g.

  • #123 (decimal)
  • #-5 (decimal)
  • #0b00010010 (binary)
  • #-0b0101 (binary)
  • #0xA2 (hex)
  • #0o107 (octal)

Comments

Comments are parts of the assembly file ignored by the assembler.

A comment is anything after and including // on a line until the end of the line.