# Lab 4

Deadline: End of lab session Tuesday, July 16th

## Objectives

• The student will be able to practice debugging RISC-V assembly code.
• The student will be able to write RISC-V functions that use pointers.

## Setup

Pull the lab files from the lab starter repository with

``````git pull staff master
``````

## RISC-V Simulator

Like in previous weeks, we will be using the Venus RISC-V simulator (can be found online here).

### Assembly/Venus Basics

• Enter your RISC-V code in the “Editor” tab
• Programs start at the first line regardless of the label. That means that the `main` function must be put first.
• Programs end with an `ecall` with argument value 10. This signals for the program to exit. The ecall instructions are analogous to System Calls and allow us to do things such as print to the console or request chunks of memory from the heap.
• Labels end with a colon (`:`).
• Comments start with a pound sign (`#`).
• You CANNOT put more than one instruction per line.
• When you are done editing, click the “Simulator” tab to prepare for execution.

For the following exercises, please save your completed code in a file on your local machine. This is crucial for the checkoff portion to work.

## Exercise 1: Debugging `megalistmanips.s`

In Lab 3, you completed a RISC-V procedure that applied a function to every element of a linked list. In this lab, you will be working with a similar (but slightly more complex) version of that procedure.

Now, instead of having a linked list of `int`’s, our data structure is a linked list of `int` arrays. Remember that when dealing with arrays in `struct`’s, we need to explicitly store the size of the array. In C code, here’s what the data structure looks like:

``````struct node {
int *arr;
int size;
struct node *next;
};
``````

Also, here’s what the new `map` function does: it traverses the linked list and for each element in each array of each `node`, it applies the passed-in function to it, and stores it back into the array.

``````void map(struct node *head, int (*f)(int)) {
for (int i = 0; i < head->size; i++) {
}
}
``````

### Action Item

Record your answers to the following questions in a text file. Some of the questions will require you to run the RISC-V code using Venus’ simulator tab.

1. Find the five mistakes inside the map function in `megalistmanips.s`. You can paste its contents into the Venus editor to open it in Venus. Read all of the commented lines under the map function in megalistmanips.s (before it returns with jr ra), and make sure that the lines do what the comments say. Some hints:
• Why do we need to save stuff on the stack before we call `jal`?
• What’s the difference between `add t0, s0, x0` and `lw t0, 0(s0)`?
• Pay attention to the types of attributes in a `struct node`.
• Note: you need only focus on `map`, `mapLoop`, and `done` functions but it’s worth understanding the full program.
• Note: you may not use any `s` registers outside of `s0` and `s1`.
2. Make an ordered list of each of the five mistakes, and the corrections you made to fix them (for checkoff).
3. Save your corrected code in a file `megalistmanips.s`. Running on Venus, you should see the following output:
``````Lists before:
5 2 7 8 1
1 6 3 8 4
5 2 7 4 3
1 2 3 4 7
5 6 7 8 9

Lists after:
30 6 56 72 2
2 42 12 72 20
30 6 56 20 12
2 6 12 20 56
30 42 56 72 90
``````

### Checkpoint

At this point, make sure that you are comfortable with the following. Note that these will not be part of the lab checkoff, but are meant to benchmark how comfortable you are with the material in the exercise.

• You should know how to debug in Venus, including stepping through code and inspecting the contents of registers.
• You should understand how RISC-V interfaces with memory.
• You should understand CALLER/CALLEE conventions in RISC-V.

## Exercise 2: Write a function without branches

Consider the discrete-valued function `f` defined on integers in the set` {-3, -2, -1, 0, 1, 2, 3}`. Here’s the function definition:

``````f(-3) = 6
f(-2) = 61
f(-1) = 17
f(0) = -38
f(1) = 19
f(2) = 42
f(3) = 5
``````

### Action Item

1. Implement the function `discrete_fn.s` in RISC-V, with the condition that your code may NOT use any branch and/or jump instructions! You can paste the file’s contents into the Venus editor and edit there if you’d like.
2. Save your corrected code in a file `discrete_fn.s`.

## Checkoff

1. Upload your completed `megalistmanip.s` and `discrete_fn.s` files to the Lab4 Autograder Gradescope assignment. Show the autograder score to your TA at checkoff. Note: this Gradescope autograder doesn’t directly contribute to your lab grade - you still need to collect a token from your TA and upload it to the Lab04 Checkoff Gradescope assignment.
2. Describe the changes you had to make for `megalistmanips.s` to your TA.