General Info¶
pqr5asm is an assembler which translates RISC-V assembly to binary/hex code.
| ISA compliance | RV32IM (User-Level ISA v2.2) — 45 base instructions + pseudo/custom instructions |
| Input | Assembly program with .s extension |
| Output | Binary/Hex code for program & data in ASCII text and .bin formats:sample_imem.bin – Program binarysample_imem_bin.txt – Binary text file of program, human readablesample_imem_hex.txt – Hex text file of program, human readablesample_dmem.bin – Data binarysample_dmem_bin.txt – Binary text file of data, human readablesample_dmem_hex.txt – Hex text file of data, human readable |
Syntax rules¶
-
One instruction per line.
-
Every program requires the program section,
.section .text, and the base address of the program should be defined by the linker directive,.org, for eg:.section .text .org 0x00000000 -
Supports
<space>,<comma>, and<linebreak>as delimiters, for eg:LUI x5 255 LUI x5, 255 -
Use
#for inline/newline comments, for eg:LUI x5, 255 # This is a sample comment -
Supports 32-bit signed/unsigned integer,
0xhex literals for immediate. For eg:255,0xFF,-255Immediates support parenthesis format for instructions with immediate offset:
addi x1, x0, 2 <=> addi x1, 2(x0)Immediate gets truncated to 20-bit or 12-bit based on instruction.
-
Registers support different ABI names which are case-insensitive.
-
%hi()and%lo()are assembly functions which can be used to extract the most significant 20 bits and least significant 12 bits from a 32-bit symbol. This is useful to generate a 32-bit address for load/store operations, or load a 32-bit constant to a register. For eg:# a4 <-load- from myvar in memory LUI a5, %hi(myvar) LW a4, %lo(myvar)(a5) # a4 -store-> to myvar2 in memory LUI a5, %hi(myvar2) SW a4, %lo(myvar2)(a5) # x1 <-load- "0xdeadbeef" LUI x1, %hi(0xdeadbeef) ADDI x1, x1, %lo(0xdeadbeef) -
%pcrel_hi()and%pcrel_lo()are similar to%hi()and%lo(), but the value returned is PC-relative rather than absolute. The pair is used together to call subroutines anywhere across the addressing space. For eg:# ra <-load- return address and jump to myfunc() AUIPC ra, %pcrel_hi(myfunc) JALR ra, %pcrel_lo(myfunc)(ra)These two functions are expected to be used together always, since
%pcrel_lo()uses its counterpart%pcrel_hi()as the reference to generate the PC-relative address. -
Supports labels for jump/branch instructions. Label is recommended to be of max. 16 ASCII characters, should be stand-alone in a new line, and is case-sensitive. For eg:
FIBONACC: mvi x1, 1 -
Supports ASCII characters in the immediate values for instructions like
MVI,LI. For eg:MVI x0, 'A'— equivalent toMVI x0, 0x41Supports all 7-bit ASCII characters from0x20to0x7E,\n,\r,\t.
Invoking the assembler¶
python pqr5asm.py -file=<assembly source file path> -pcrel
-pcrel: Applying this flag uses PC-relative addressing for instructions LA, JA. This helps in generating relocatable binary code. If this flag is not used, absolute address is loaded by the instructions, and the generated binary code may not be relocatable.
Assembler flow¶
- Assembly code file → validate all sections, linker directives → initial formatting →
- Pre-processing: decode all labels and symbols and resolve all addresses → resolve all assembly functions and immediates → final formatting →
- Parse instructions line-by-line → dump binary code files on successful compilation.
Attention
Earlier versions of this manual shipped only as pqr5asm_imanual.pdf — see Changelog for what's new.