Risc-V Learning Summary
Enjoying and Hating assembly.
Recently, I self-learned the cs61c(su20) class, which requires you to write a risc-v
program to make a simple neural network in the project 2. It could be annoying that you write some bug in the assembly since the debug condition is frustrating. After all, through the project I learned a lot about risc-v, especially the calling conventions(at the beginning I haven't paid much attention to it, and it had really caused a lot of problems to my work). After all, I summarized some things that seem important to risc-v assembly coding.
Calling Conventions
It is very important to assembly coding. To make things work properly, you should follow calling conventions, especially when your project grows bigger and bigger.
The Caller's Responsibility
The caller should manage its temporary variables like t0
, a0
and ra
. Since these variables are used for temporary purposes and in many cases many temporary variables are randomly used, the callee have no responsibility to save the caller's temporary variables, which makes variable management easy.
When the caller calls a function, make sure you have stored those temporary variables which carries information through the processes. The following demo demonstrates the principle:
|
|
The Callee's Responsibility
The callee should save the long-life variables(like s0
) before doing its work, and revert them after the work before return.
However, there are many long-life variables(12 variables' name begins with the character 's'), should we save all of them? Absolutely no. You only need to save those variables that will be used in the following callee's work. For example:
|
|
Multiple File Example
main
file
|
|
function
file
|
|
It should be noticed that the exposing function(label) only exposed its label name and address (my understanding), and its end is the ret
, however the compiler doesn't know where its end is.
Pass Command Line Arguments to the Program
If you don't change a-beginning variables at the beginning, then a0
is argc
(int
type), and a1
is argv
(char **
type). RISC-V handles command line arguments in the same way as C, which means a1[0]
is the program itself. You can load command line arguments like this:
|
|
Ecall - The Environmental Calls
You can refer to venus - Environmental Call. The starter code for the project2 is also a good example: https://github.com/61c-teach/su20-proj2-starter/blob/master/src/utils.s
Resources
- resc-v reference and large version
- unoffical risc-v manual
- venus wiki
it contains useful information likeAssembler Directives
andEnvironmental Calls
- cs61c venus reference mainly about
venus
tool, but also contains some RISC-V knowledge