Monday 28 March 2022

RISC-V: Initialisation and C run-time

Start Simple

Our simplest assembly program simply exits cleanly, calling Linux to return to the Operating System.  We can assemble it to an object module and link it as an executable successfully.  We check it works by testing the return code.


Save Return Address and pass Arguments across

When we write C programs there is an initialisation routine which is usually called something like crt0.s, which carries out initialisation for us.  My starting point for crt0.s is a program which saves the return address in the stack, which has already been setup for us.  As we exit the program using an OS call this isn't really necessary but I feel this is a good thing to do.
Next we can initialise the command line arguments which are passed  from the OS in the stack.  We put them in argument registers a0 and a1.  We can now call the C function main.c. 
Providing my main.c program doesn't contain any clib subroutine calls it should work as the sample below shows.  crt0.s calls main.c to add up a few numbers.  main.c returns the answer which crt0.s passes back to linux in the return code.


This is very good, we simply have two object modules crt0.o and main.o linked together into an executable which runs.  In fact I don't think we need to save the return address or setup args in crt0, we can just call a "pure" C function and it will run.  Our main.c function can make linux syscalls, but isn't allowed to use clib (stdio.h etc).  

Using assembly subroutines to do I/O for my C program

The example below shows a main.c module which has command line arguments passed to it from crt0.s and calls my own assembly write.s subroutine to display the first command line argument - which is the name of the invoking command  ./crt0.


Conclusion

The next logical step is to make our own library of c functions.  On previous occasions I have tried to build / use newlib, but without success.  The situation remains unchanged.  I think I have found a better newlib version to use but I would be advised to try building it on ARM before RISC-V.

However, we have made excellent progress and have a better understanding of the C environment.



No comments:

Post a Comment