I want to write a simple RISCV program in assembly and then test it. The program should simply load a value into a register and add a value to it:
.file "hello.c"
.text
.align 2
.globl main
.type main, @function
main:
li a0, 2
add a0, a0, 7
.size main, .-main
.ident "GCC: (GNU) 5.3.
However, when I type in:
riscv64-unknown-elf-gcc hello.s
spke -d pk a.out
reg 0 a0
It always returns 0x0000000000000000. Why? What am I doing wrong?
When you start spike with -d, the command prompt is printed before any instructions are executed.
Disassemble your compiled program to see all the instructions wrapped around your two instruction main() subroutine.
riscv64-unknown-elf-objdump -d hello | less
Disassembly of section .text:
0000000000010000 <_ftext>:
10000: 00002197 auipc gp,0x2
...
0000000000010164 <main>:
10164: 00200513 li a0,2
10168: 00750513 addi a0,a0,7
I told spike to run to the first instruction of main, then single stepped, and then displayed register a0:
$ spike -d pk foo
Note: Hitting enter is the same as: run 1
: until pc 0 0x0000000000010164
: pc 0
0x0000000000010164
: run 1
core 0: 0x0000000000010164 (0x00200513) li a0, 2
: reg 0 a0
0x0000000000000002
: run 1
core 0: 0x0000000000010168 (0x00750513) addi a0, a0, 7
: reg 0 a0
0x0000000000000009
As commenter Peter points out, a procedure usually returns at the end. In the case of main, it falls through to atexit(), etc.
You can use the "r" command to see the complete execution trace of "pk hello".