# RISC-V Assembly Code Examples

## Learning RISC-V Assembly code trough simple examples and exercises

--

A lot of RISC-V example code jumps straight into fairly complex code examples. I intend to start slow do some very simple examples.

For a proper introduction to things such as registers, conditional branching and assembly code format, I advice reading: RISC-V Assembly for Beginners.

That is an overview story, but does not contain that many examples. As with the first article we will use the online Cornell University RISC-V interpreter.

When working through the code examples, you could print out this RISC-V reference sheet to help you: James Zhu’s RISC-V Reference.

The most important instructions are probably:

• `ADDI rd, zero, immediate`, to load a value (`immediate`) into register `rd`.
• `LW rd, offset(rs1)` to load content at memory location `offset + rs1` into register `rd`.
• `SW rd, offset(rs1)` store content of `rd` register at memory location `offset + rs1`.
• `ADD rd, rs1, rs2` to content of two registers and store value in destination register `rd`.
• The branch instructions `BEQ`, `BNE`, `BLT`. Read previous story for more details.

# Input Doubler

Let us begin with a really simple example. You are writing a function which doubles the its input. If you read my previous intro: RISC-V Assembly for Beginners.

You should know that on RISC-V functions get their inputs in registers `a0`, `a1`, up to `a7`. These are just aliases for registers starting at `x10`.

Jot down a solution before looking at my solution below:

`doubler:   ADD a0, a0, a0`

To test this put an initial value in register `a0` before running the code in the simulator. If it works, then `a0` should be doubled. Functions should return their result in `a0` so this is correct way of doing it.

If this was real function which got called from somewhere else, we would need this line at the end to return from function:

`JALR zero, ra, 0`