RISC-V instruction set architecture (ISA) is designed to support computer architecture research and education, and completely free for academia and industry use. By using the reference of RISCV-Angel, which is running with the RV64 (64-bit) architecture. My task is to make sure that the RISCV-Angel is able to run on the RV32 (32-bit) architecture as well. The debugging of the Hello_World program is not going well as I am still getting the “undefined error 0”. Thanks to my supervisor, whom taught me on the usage of “readelf” and “objdump” in the terminal instead of the “hexedit’ that I tried to use previously. These commands are extremely useful in monitoring the contents of the executable file, including the headers and section information.

Usage of ReadELF amd Objdump

The proper way to debug the Hello_World executable file is to follow the pipeline architecture, which also need to be done along with the RISC-V instruction manual. The initial problem was fixing the ELF header decoding by the RISC-V, in which the default one was decoding the 64-bit ELF header. However, the problem still exists after changing the ELF header decoding and ensured that entry address and the instruction is running correctly. The debugging is taking much time as I need to track each general register that has been updated with, and taking the result for each following computation. These debugging also makes me feel confused sometimes, especially when there is something wrong with the instruction that is being running through. One of the problem I found was the storing values in negative arrays, the instruction that has been running on, computed a negative effective byte address from the register values and offset, for storage array numbers, which is not an defined array that can be used.

The RISC-V Assembly Guide with only GNU Tool

The best way that I found, recommended by my supervisor, is to test out whether the 32-bit instruction is running properly is by using the assembly code. It is efficient and fairly easy to use by referring to the instruction manuals and some internet example on writing assembly code. However, it comes with a hardship to figure out how to compile the assembly code into the executable file that can be read by RISC-V. After several trial using the RISC-V tools and comparing with the normal GNU tools, I found out that the following code can be used to produce an executable file for the RISC-V engine. First of all, we need to write a simple assembly code that can be compiled.


The “.text” is a section to store our codes and the “.data” section is used to set any declaration variables that we use.

riscv32-unknown-elf-as file.S -o file.o -m32
riscv32-unknown-elf-ld -s -o exec_name file.o

The code above will produce an executable file with “exec_name”. Then, the executable file is fed into the RISC-V and run the instructions in it. The “riscv32-unknown-elf-as” command stands for RISC-V assembler, which assemble the assembly code into an object file. The object file is then linked by using the ” riscv32-unknown-elf-ld” linker to produce an executable file.

Note : We are using the default RISC-V linker script.

Alternative to Finding the Problem

By creating new executable file using the RISC-V Assembler and Linker, each instruction is verified one by one by comparing with the instruction manual. The most unexpected things from all the output of verification was all the instructions is running correctly. This shifted my thoughts on the instruction to the C program that I had been written for the Hello_World. With several trials in creating new executable file for the testing of RISC-V, I found out that there is a similar pattern from the executable file, in which all the instructions is stopped at the same instruction set “0000 8067” and all the files did not actually reach the “main section” instruction yet. This happens same to the empty main function that I created to try out my guess. It happens that all the instructions that been running, will eventually lead to the same “__register_exitproc” section.


I am guessing that it means that the register that stores the exit procedure. I was not fully convinced until I compared it with the assembly code that finishes in the last piece of instruction, they gave the same error of “undefined error 0”, stating that the 0000 0000 address is undefined to be executed, which the program is actually ended here.

In conclusion, it is proven that the RISC-V Angel is able to run all the 32-bit ISA correctly. There might be some problem with the RISC-V 32-bit GNU compiler which makes it unable to run the C program instructions properly.