-
Notifications
You must be signed in to change notification settings - Fork 0
Assembly
ByteFrost Assembly language offers some abstraction above the ByteFrost instruction set. Note that there are some differences between the two, as well as overloaded instruction names.
Assembly Instruction | Use | Syntax | Instruction it's based on | Differences from instruction set | Affects Flags |
---|---|---|---|---|---|
LDR | Loads register with immediate value | LDR Rd, #Imm |
LDR, opcode 3 | No difference | No |
MOV | Copy value of one register and store in another | MOV Rd, Rs |
MOV, opcode 4 | No difference | No |
ALU instructions have two variants based on opcodes 2 and 6 of the instruction set. This is reflected in assembly as overloading ALU function names with two accepted parameter sequences: (function) Rd, Rs1, Rs2
and (function) Rd, #Imm
.
The first takes the values of Rs1
and Rs2
as inputs to the ALU and stores the result of the ALU function in Rd
. The second takes the value of Rd
and the immediate value #Imm
as inputs to the ALU and stores the result in Rd
.
Note: In practice,
(function) Rd, #Imm
operates as(function) Rd, Rd, #Imm
, meaningRd
is used as the first argument and#Imm
as the second argument. This is important for some ALU functions where order matters, such asSUB
. Also, note that the immediate value#Imm
is a 4-bit immediate, not an 8-bit immediate.
Assembly Instruction | Use | Syntax | Alternate syntax | Instruction it's based on | Differences from instruction set | Affects Flags |
---|---|---|---|---|---|---|
OR | Bitwise OR | OR Rd, Rs1, Rs2 |
OR Rd, #Imm |
ALU, opcode 2 or 6 (for alternate syntax) | OR function has specified assembly instruction | Yes |
AND | Bitwise AND | AND Rd, Rs1, Rs2 |
AND Rd, #Imm |
ALU, opcode 2 or 6 (for alternate syntax) | AND function has specified assembly instruction | Yes |
XOR | Bitwise XOR | XOR Rd, Rs1, Rs2 |
XOR Rd, #Imm |
ALU, opcode 2 or 6 (for alternate syntax) | XOR function has specified assembly instruction | Yes |
NOT | Bitwise NOT | NOT Rd, Rs1, Rs2 |
NOT Rd, #Imm |
ALU, opcode 2 or 6 (for alternate syntax) | NOT function has specified assembly instruction | Yes |
ADD | Adds values of two registers | ADD Rd, Rs1, Rs2 |
ADD Rd, #Imm |
ALU, opcode 2 or 6 (for alternate syntax) | ADD function has specified assembly instruction | Yes |
SUB | Subtracts value of one register from another | SUB Rd, Rs1, Rs2 |
SUB Rd, #Imm |
ALU, opcode 2 or 6 (for alternate syntax) | SUB function has specified assembly instruction | Yes |
ASL | Arithmetic shift left by 1 bit | ASL Rd, Rs1, Rs2 |
ASL Rd, #Imm |
ALU, opcode 2 or 6 (for alternate syntax) | ASL function has specified assembly instruction | Yes |
ROL | Rotate left by 1 bit using carry | ROL Rd, Rs1, Rs2 |
ROL Rd, #Imm |
ALU, opcode 2 or 6 (for alternate syntax) | ROL function has specified assembly instruction | Yes |
LSR | Logical shift right by 1 bit | LSR Rd, Rs1, Rs2 |
LSR Rd, #Imm |
ALU, opcode 2 or 6 (for alternate syntax) | LSR function has specified assembly instruction | Yes |
ASR | Arithmetic shift right by 1 bit | ASR Rd, Rs1, Rs2 |
ASR Rd, #Imm |
ALU, opcode 2 or 6 (for alternate syntax) | ASR function has specified assembly instruction | Yes |
ROR | Rotate right by 1 bit using carry | ROR Rd, Rs1, Rs2 |
ROR Rd, #Imm |
ALU, opcode 2 or 6 (for alternate syntax) | ROR function has specified assembly instruction | Yes |
ADC | Adds values of two registers and carry | ADC Rd, Rs1, Rs2 |
ADC Rd, #Imm |
ALU, opcode 2 or 6 (for alternate syntax) | ADC function has specified assembly instruction | Yes |
SBC | Subtracts value of one register from another and adds carry | SBC Rd, Rs1, Rs2 |
SBC Rd, #Imm |
ALU, opcode 2 or 6 (for alternate syntax) | SBC function has specified assembly instruction | Yes |
There are assembly instructions that use the ALU to update flags but which do not save the output of the ALU's operation. These instructions are meant to ease implementation of conditional branching by eliminating the need to overwrite a register to determine whether the branch should occur. These are listed below:
Assembly Instruction | Use | Syntax | Alternate Syntax | Instruction it's based on | Affects Flags |
---|---|---|---|---|---|
COMP | Compares register value with another register or immediate by subtraction without saving result | COMP Rs1, Rs2 |
COMP Rs1, #Imm |
Test and Test immediate, opcodes 12 and 13 | Yes |
TST | Compares register value with 0 | TST Rs |
None | Test immediate, opcode 13 (equivalent to COMP Rs1, #0 ) |
Yes |
Finally, there are some "syntactic sugar" assembly instructions that are built on-top of existing instructions. These are listed below:
Assembly Instruction | Use | Syntax | Alternate syntax | Instruction it's based on | Affects Flags |
---|---|---|---|---|---|
INC | Increments value of register by 1 | INC Rd |
None | ALU immediate, opcode 6 (is equivalent to ADD Rd, #1 ) |
Yes |
DEC | Decrements value of register by 1 | DEC Rd |
None | ALU immediate, opcode 6 (is equivalent to SUB Rd, #1 ) |
Yes |
Like ALU assembly instructions, branching instruction names are overloaded to reflect absolute and relative branch instructions in the instruction set, opcodes 5 and 7, respectively. Hence the two supported parameter sequences are (Condition) #Imm
for absolute branching and (Condition) +/-Imm
for relative branching.
Absolute branching example: BEQ #5
- this will set the current line to 5 if the zero flag is high.
Relative branching example: BEQ -2
- this will set the current line to the current line minus 2 if the zero flag is high.
Important Note: Assembly instructions do differ here from the instruction set by that the specified immediate in assembly code is actually 1 larger than the compiled immediate. In absolute branching, the reason is that the line number in a text-editor is 1-indexed, while the program counter is 0-indexed. In relative branching, this is because the program counter always points at the next instruction. I.e. if the program counter fetched the instruction at address 0, it will already store the address 1 while the instruction that was loaded is being run. So for instance, intuitively
JMP -1
should go to the previous line, but if implemented as is, this will actually keep the PC in place as the PC already points to the next instruction. Hence the compiled machine language code will have the immediate -2 instead.
Assembly Instruction | Use | Absolute branching syntax | Relative branching syntax | Affects Flags |
---|---|---|---|---|
JMP | Unconditional jump | JMP #Imm |
JMP +/-Imm |
No |
BMI | Branch on minus (if negative flag is high) | BMI #Imm |
BMI +/-Imm |
No |
BCS | Branch on carry set (if carry flag is high) | BCS #Imm |
BCS +/-Imm |
No |
BEQ | Branch if equal (if zero flag is high) | BEQ #Imm |
BEQ +/-Imm |
No |
BPL | Branch on plus (if negative flag is low) | BPL #Imm |
BPL +/-Imm |
No |
BCC | Branch on carry clear (if carry flag is low | BCC #Imm |
BCC +/-Imm |
No |
BNE | Branch if not equal (if zero flag is low) | BNE #Imm |
BNE +/-Imm |
No |
There are four instructions in the instruction set dedicated to handling stack operations: PUSH
, POP
, JSR
(Jump SubRoutine), and RTS
(ReTurn Subroutine). ByteFrost assembly makes no significant alterations to these instructions:
Assembly Instruction | Use | Syntax | Instruction it's based on | Affects Flags |
---|---|---|---|---|
PUSH | Store register on the stack and increment stack pointer | PUSH Rs1 |
PUSH, opcode 14 | No |
POP | Decrement stack pointer and load a register with value on the stack | POP Rd |
POP, opcode 15 | No |
JSR | Jump to subroutine at given address | JSR #Imm |
JSR, opcode 16 | No |
RTS | Return from subroutine to return address on the stack | RTS |
RTS, opcode 17 | No |
Important Note: As with branching, the JSR instruction does differ from the instruction set as the specified immediate address in assembly is actually one larger than the compiled immediate. This is because the assembly program line numbers are 1-indexed, whereas in the binaries they are 0-indexed (the program counter begins at address 0, not 1).
There are multiple ways to read to / write from RAM using ByteFrost assembly. Currently these are:
Assembly Instruction | Use | Syntax | Instruction it's based on | Affects Flags |
---|---|---|---|---|
LMA | Load from address to register | LMA Rd, #Imm |
LMA, opcode 9 | No |
SMA | Store to address from register | SMA Rs, #Imm |
SMA, opcode 10 | No |
LMR | Load from address in Rs to Rd
|
LMR Rd, Rs |
LMR, opcode 11 | No |
SMR | Store from Rd to address in Rs
|
SMR Rd, Rs |
SMR, opcode 12 | No |
Examples:
-
LMA R1, #5
will load the value stored in address 5 into registerR1
-
SMA R1, #5
will store the value inR1
in address 5 -
LMR R0, R1
will load the value in the address stored inR1
intoR0
-
SMR R0, R1
will store the value inR0
to address inR1
ByteFrost assembly includes instructions to print values to the display. The instruction name OUT
is overloaded with two
parameter sequences.
Assembly Instruction | Use | Syntax | Instruction it's based on | Affects Flags |
---|---|---|---|---|
OUT | Prints value stored in register either as an ASCII character (with 'A' option) or as an integer (with 'I' option) | OUT Rd, A/I |
OUT, opcode 8 | No |
OUT | Prints immediate value either as an ASCII character (with 'A' option) or as an integer (with 'I' option) | OUT #Imm, A/I |
OUT immediate, opcode 14 | No |
Using the 'A' option, the given value is printed as an ASCII character. Note that the ByteFrost display's character set is not equivalent exactly to ASCII - the character set used by ByteFrost is listed here. Additionally, the display's character set has undefined ranges, so we added our own characters to fill these (this is taken care of by the display card).
An important difference is that the values 0
through 15
print the values 0
through F
in hexadecimal. This means that OUT #3, A
will print 3
.
There are also some derived characters which are understood only by the display card (Arduino Nano), such as the new-line character.
Using the 'I' option, the given value is printed as an integer. Notice that the format for this is in hexadecimal only, so the instruction OUT #5, I
will be printed as 05
on the display.
Miscellaneous instructions that don't fit any other category are listed below:
Assembly Instruction | Use | Syntax | Instruction it's based on | Differences from instruction set | Affects Flags |
---|---|---|---|---|---|
NOP | No operation | NOP |
NOP, opcode 0 | No difference | No |
BRK | Halt operation | BRK |
BRK, opcode 1 | No difference | No |