Registers

The assembler supports 25 registers. These registers can be used for general-purpose operations or not.

RegisterSuggested UsageA BusB BusC Bus
MarMemory AddressOutput
MdrMemory DataInputInputOutput
MbrMemory BufferInput
MbruMemory BufferInput
Mbr2Memory BufferInput
Mbr2uMemory BufferInput
PcProgram CounterInputOutput
CppCall PointerInputInputOutput
LvLocal VariableInputInputOutput
RaReturn AddressInputInputOutput
T0TemporaryInputInputOutput
T1TemporaryInputInputOutput
T2TemporaryInputInputOutput
T3TemporaryInputInputOutput
S0SavedInputInputOutput
S1SavedInputInputOutput
S2SavedInputInputOutput
S3SavedInputInputOutput
S4SavedInputInputOutput
S5SavedInputInputOutput
S6SavedInputInputOutput
A0Function ArgInputInputOutput
A1Function ArgInputInputOutput
A2Function ArgInputInputOutput
A3Function ArgInputInputOutput

Sections

The assembler supports two sections: .text and .data. The sections are defined as follows:

.text Section

The .text section contains the executable instructions.

.data Section

The .data section is used for declaring and initializing data.

Instruction Format

Most vondel instructions in follow the format: opcode dest_regs <- source1, source2. Here's a breakdown of the components:

  • opcode: Specifies the operation to be performed.
  • dest_regs: The registers where the result will be stored.
  • source1 and source2: Registers or immediate values used as operands.

Supported Instructions

The assembler supports the following instructions:

Add

Adds two registers and save the result into 1 up to 20 registers that are allowed in the C_bus

add t0, t1, s0, a2, ra <- a0, a1

Sub

Subtract x - y and store on registers

sub t0, t1, s0, a2, ra <- a0, a1

Mul

Multiplies the value of x and y and store on registers

mul s0, a2, ra <- a0, a1

WARNING: Mul cannot be used with t* registers

Mul2

Multiplies the value of x and y and store on registers

mul s0, a2, ra <- a0, a1

INFO: More performatic and can use t* registers

Div

Divides x by y and store on registers

div t0, t1, s0, a2, ra <- a0, a1

Mod

Gets the remainder of x by y and store on registers

mod t0, t1, s0, a2, ra <- a0, a1

And

Makes a bitwise and with x and y

and t0, t1, s0, a2, ra <- a0, a1

Or

Makes a bitwise or with x and y

or t0, t1, t2, s0, s1, a2, ra <- a0, a1

Xor

Makes a bitwise xor with x and y

xor t0, t1, t2, s0, s1, a2, ra <- a0, a1

Not

Stores the result of !x on the registers

not t0, t1, t2, s0, s1, a2, ra <- a0

It uses only a single register as source

Sll

Stores the result of x << 8 on the registers

sll t0, t1 <- a0

It uses only a single register as source

Sla

Stores the result of x << 1 on the registers

sla t0, t1 <- a0

It uses only a single register as source

Sra

Stores the result of x >> 1 on the registers

sra t0, t1 <- a0

It uses only a single register as source

Read

Load a value from memory on the address addr into a register

read t0, t1, t2 <- addr
read t0, t1, t2 <- 77

Addr can be both a label referencing a variable in .data section or a immediate with value of 0 to 255

Write

Store a value from a register x into memory on address addr

write addr <- t1
write 77 <- ra

It allows only a single register as source

Addr can be both a label referencing a variable in .data section or a immediate with value of 0 to 255

Jal

Jump inconditionally to a label

jal loop

Beq

Branch if equal (jump to a label if x and y are equal)

beq t0, t1, done

Bne

Branch if not equal (jump to a label if x and y are not equal)

bne t0, t1, done

Blt

Branch if less then (jump to a label if x is less then y)

blt t0, t1, done

Bgt

Branch if greater then (jump to a label if x is greater then y)

bgt t0, t1, done

Lui

Load upper immediate imm on registers

lui t0, t1,t2 <- imm
lui t0, t1,t2 <- 77

It takes only a single immediate as parameter

Imm can be both a label referencing a .byte in .data section or an immediate with value of 0 to 255

Addi

Adds a register x and a immediate imm and save this value on registers

addi t0, t1,t2 <- t0, imm
addi t0, t1,t2 <- a2, 77

The first argument must be a register and the second a immediate

Imm can be both a label referencing a .byte in .data section or an immediate with value of 0 to 255

Muli

Multiplies a register x and an immediate imm and save this value on registers

muli t0, t1,t2 <- t0, imm
muli t0, t1,t2 <- a2, 77

The first argument must be a register and the second an immediate

Imm can be both a label referencing a .byte in .data section or an immediate with value of 0 to 255

Divi

Divides a register x by an immediate imm and save this value on registers

divi t0, t1,t2 <- t0, imm
divi t0, t1,t2 <- a2, 77

The first argument must be a register and the second an immediate

Imm can be both a label referencing a .byte in .data section or an immediate with value of 0 to 255

Modi

Get the remainder of a div between a register x by an immediate imm and save this value on registers

modi t0, t1,t2 <- t0, imm
modi t0, t1,t2 <- a2, 77

The first argument must be a register and the second an immediate

Imm can be both a label referencing a .byte in .data section or an immediate with value of 0 to 255

Subi

Subtracts from register x the value of an immediate imm and save this value on registers

subi t0, t1 <- t0, imm
subi t0, t1 <- a2, 77

The first argument must be a register and the second an immediate

Imm can be both a label referencing a .byte in .data section or an immediate with value of 0 to 255

Andi

Makes a bitwise and of register x and an immediate imm, then saves this value on registers

andi t0, t1 <- t0, imm
andi t0, t1 <- a2, 77

The first argument must be a register and the second an immediate

Imm can be both a label referencing a .byte in .data section or an immediate with value of 0 to 255

Ori

Makes a bitwise or of register x and an immediate imm, then saves this value on registers

ori t0, t1 <- t0, imm
ori t0, t1 <- a2, 77

The first argument must be a register and the second an immediate

Imm can be both a label referencing a .byte in .data section or an immediate with value of 0 to 255

Xori

Makes a bitwise xor of register x and an immediate imm, then saves this value on registers

xori t0, t1 <- t0, imm
xori t0, t1 <- a2, 77

The first argument must be a register and the second an immediate

Imm can be both a label referencing a .byte in .data section or an immediate with value of 0 to 255

Mov

Store the value of the register x on the registers

mov t0, t1, t2 <- a1
mov ra, s1, s2, s3 <- t0

It supports only a single register as parameter

Halt

Stop the program execution

halt

Just halt

Data Declaration Instructions (.data section)

  • .byte: Declare a byte-sized data item
  • .word: Declare a word-sized (4 bytes) data item

Labels and Branching

Labels can be defined and used as targets for branching instructions. Here are the guidelines for labels and branching:

  • Labels are defined by placing a colon (:) after the label name (e.g., label:).
  • Branching instructions can use labels as targets (e.g., beq t1, t2, label).

Comments

Comments start with a semicolon (;) or (#) and continue until the end of the line. Comments are ignored during assembly.

Addressing Modes

The assembler supports two addressing modes: immediate and register addressing. Here's how they are used:

  • Immediate values can be specified directly in the instruction.
  • Registers have the ABI form of RISC V

This specification provides a general outline for the assembler language. Additional details, such as specific opcode mappings and assembly directives, can be added as needed.