Debugging code can sometimes take longer than writing it. So how do we use QEMU + GDB to debug RISCV programs?
To document this process, we will write the following assembly code using the ADD instruction as an example.

We will put 1 into register x2, 2 into register x3, and then add the values of registers x2 and x3, storing the result in register x4.
A final infinite loop will prevent the program from running off.
Next, we compile this assembly code:
riscv32-unknown-elf-gcc -nostartfiles -Ttext 0x80000000 add.s -o add.elf -g
Use the following command to generate the bin file:
riscv32-unknown-elf-objcopy -O binary add.elf add.bin
Let’s check the generated file:

We can see that the bin file is smaller than the elf file because it has removed a lot of information, such as debugging information. The bin file is exactly 16 bytes because we have 4 assembly instructions, each 4 bytes, totaling 16 bytes.
You can use hexdump to view the contents of the bin file.

Now let’s start debugging:
First, start the QEMU and GDB debugging environment.

Use display to show the registers we want to check: since the program only involves registers x2, x3, and x4, we will display these three registers.

set disassemble-next-line on // Whether to show the next line of code, which helps us debug b _start // Set a breakpoint, _start is the label in the assembly code where it starts target remote : 2222 // Set the connection, QEMU specifies port 2222, so we connect to 2222 si // Step execution
Let’s take a look at the execution results of the above commands.

After connecting, we find that the value of x2 is still the initial value. Our next instruction is li x2,1. Let’s step through it with si.

After execution, we notice that x2 has been assigned the value 1.
Let’s look at the complete effect.

After executing the add instruction, the value in register x4 changes to 3, and the debugging of the initial assembly code meets our expectations.
When debugging is finished, exit the GDB debugger using quit.

This is the process of debugging RISCV programs using GDB.