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.