RISC-V is a open source instruction set architecture (ISA), developed by the university of California. This project consists in the development of an assembler for the RISC-V 64 bits ISA, made in c++, allows the conversion of the assembly language into machine language
This project aims create a fully funcional assembler, who assemble to RISCV, MIPS and ARM. Actually the project focuses on riscv isa, but is not the only objective, we planning start the implementation of another ISA's mentioned above in the near future. Also, we plan implement several optmizations like branchless, multithreading and others kinds of pratices to improve the assembler performance
The RV32I base integer ISA includes 32 registers, named x0
to x31
. The
program counter PC
is separate from these registers, in contrast to other
processors such as the ARM-32. The first register, x0
, has a special function:
Reading it always returns 0 and writes to it are ignored. As we will see later,
this allows various tricks and simplifications.
In practice, the programmer doesn't use this notation for the registers. Though
x1
to x31
are all equally general-use registers as far as the processor is
concerned, by convention certain registers are used for special tasks. In
assembler, they are given standardized names as part of the RISC-V application
binary interface (ABI). This is what you will usually see in code listings. If
you really want to see the numeric register names, the -M
argument to objdump
will provide them.
Register | ABI | Use by convention | Preserved |
---|---|---|---|
x0 | zero | hardwired to 0, ignores writes | N/A |
x1 | ra | return address for jumps | NO |
x2 | sp | stack pointer | YES |
x3 | gp | global pointer | N/A |
x4 | tp | thread pointer | NO |
x5 | t0 | temporary register 0 | NO |
x6 | t1 | temporary register 1 | NO |
x7 | t2 | temporary register 2 | NO |
x8 | s0 or fp | saved register 0 or frame pointer | YES |
x9 | s1 | saved register 1 | YES |
x10 | a0 | return value or function argument 0 | NO |
x11 | a1 | return value or function argument 1 | NO |
x12 | a2 | function argument 2 | NO |
x13 | a3 | function argument 3 | NO |
x14 | a4 | function argument 4 | NO |
x15 | a5 | function argument 5 | NO |
x16 | a6 | function argument 6 | NO |
x17 | a7 | function argument 7 | NO |
x18 | s2 | saved register 2 | YES |
x19 | s3 | saved register 3 | YES |
x20 | s4 | saved register 4 | YES |
x21 | s5 | saved register 5 | YES |
x22 | s6 | saved register 6 | YES |
x23 | s7 | saved register 7 | YES |
x24 | s8 | saved register 8 | YES |
x25 | s9 | saved register 9 | YES |
x26 | s10 | saved register 10 | YES |
x27 | s11 | saved register 11 | YES |
x28 | t3 | temporary register 3 | NO |
x29 | t4 | temporary register 4 | NO |
x30 | t5 | temporary register 5 | NO |
x31 | t6 | temporary register 6 | NO |
PC | (none) | program counter | N/A |
Registers of the RV32I. Based on RISC-V documentation and Patterson and Waterman "The RISC-V Reader" (2017)
As a general rule, the saved registers s0
to s11
are preserved across
function calls, while the argument registers a0
to a7
and the
temporary registers t0
to t6
are not. The use of the various
specialized registers such as sp
by convention will be discussed later in more
detail.
The assembler are developed in c++ 14, using boost library. The assembler supports some of RISC-V RV32LI instructions
Version | Suported instructions | ||||||
---|---|---|---|---|---|---|---|
R | I | S | B | U | J | P | |
1.1 | ADD, SUB, AND OR, XOR, SLL, SRL |
ADDI, ANDI, ORI | N/A | N/A | N/A | N/A | N/A |
1.1 | ADD, SUB, AND OR, XOR, SLL, SRL |
ADDI, ANDI, ORI XORI, SLLI, SRLI LB, LH, LW |
N/A | N/A | N/A | N/A | N/A |
DEV | ADD, SUB, AND OR, XOR, SLL, SRL |
ADDI, ANDI, ORI XORI, SLLI, SRLI LB, LH, LW, LD |
SB, SH, SW, SD | BEQ, BNE, BLT, BGE, BLTU, BGEU | N/A | N/A | N/A |
First, we need to install boost lib for c++. the Installation depends of the operating system in use.
# cloning the repository
git clone https://github.com/IcaroM-CdC/Assembler-RISC-V.git
# compiling the binaries
make compile
# executing
./assembler input_file.asm -o output_file.txt
if you want to print the assembled instructions, in terminal run the command
./assembler input_file.asm