lab03: RISC-V, Venus
相关信息
Exercise 1: Venus Basics
- local terminal:
- run:
java -jar tools/venus.jar . -dm
- with port:
java -jar tools/venus.jar . -dm --port 6162
- In the Venus web terminal
- run:
mount local labs
- with URL: 看terminal弹出的指令
Translating from C to RISC-V
#include <stdio.h>
// nth Fibonacci number
int n = 12;
// Function to find the nth Fibonacci number
int main(void) {
int curr_fib = 0, next_fib = 1;
int new_fib;
for (int i = n; i > 0; i--) {
new_fib = curr_fib + next_fib;
curr_fib = next_fib;
next_fib = new_fib;
}
printf("%d\n", curr_fib);
return 0;
}
.data
n: .word 12
.text
main:
add t0, x0, x0 # curr_fib = 0
addi t1, x0, 1 # next_fib = 1
la t3, n # load the address of the label n
lw t3, 0(t3) # get the value that is stored at the adddress denoted by the label n
- directive:
.text指令
- add:寄存器-寄存器加法(不处罚溢出异常)
- addi:寄存器-立即数加法(会触发溢出异常)
- la:load address
t3 = &n
- lw:load word
t3 = *t3
- variable:
x0 恒等于0
- 我们不能直接用
add t3, n, x0,因为n并没有存储在寄存器中
- t3是i,t2是new_fib,尚未赋值
fib:
beq t3, x0, finish # exit loop once we have completed n iterations
add t2, t1, t0 # new_fib = curr_fib + next_fib;
mv t0, t1 # curr_fib = next_fib;
mv t1, t2 # next_fib = new_fib;
addi t3, t3, -1 # decrement counter
j fib # loop
finish:
addi a0, x0, 1 # argument to ecall to execute print integer
addi a1, t0, 0 # argument to ecall, the value to be printed
ecall # print integer ecall
addi a0, x0, 10 # argument to ecall to terminate
ecall # terminate ecall
- Printing is a system call.
- The first argument specifies what we want
ecall to do (in this case, print an integer). To specify that we want to print an integer, we pass a 1.
- The second argument is the integer that we want to print out.
- To pass an argument, we need to place it in an argument register (
a0-a7).
Exercise 2: Using the Venus Debugger
- Click the "prev" button to undo the last executed instruction. Note that undo may or may not undo operations performed by
ecall, such as exiting the program or printing to console.
Venus: Memcheck 金星:Memcheck
.import utils.s
.text
main:
# This program will fill an array of size 10 with 0's
# Allocate an array of size 10
li a0 40 # 10 ints, 4 bytes each
jal malloc # malloc is defined in utils.s
mv t0 a0 # the pointer is returned in a0
# Fill the array with 0's
li t1 0 # t1 is the index
li t2 10 # t2 is the size of the array
- li:
- load immediate:
li rd, imm
- rd为目标寄存器
- jal:
- jump and link:
jal, rd, offset
- offset为有符号立即数
- mv:
MV rd, rs → ADDI rd, rs, 0
- 复制值
loop:
# Store 0 at the current index
sw x0 0(t0)
# Increment the index
addi t1 t1 1
# Increment the pointer
addi t0 t0 4
# Check if we are done
# If not, loop
bge t2 t1 loop
# Exit the program
li a0 0
jal exit
- bge:
- branch if greater or equal, 2's complement
- sw:
- store word:
sw rs2, offset(rs1)
- 数据从通用寄存器写入内存
- sw是存值入地址,lw是从地址读值
Exercise 3: Using Memcheck
Exercise 4: Array Practice
f:
# Your code here
addi t0 a0 3 # a0 init{-3,-2,-1...} ---> t0 init{0,1,2...}
slli t1 t0 2 # relative index:t1 = t0 * 4 = {0, 4, 8, 12...}
add t1 t1 a1 # absolute index: t1 = t1 + a1
lw a0 0(t1) # reference
Exercise 5: Factorial
# factorial takes one argument:
# a0 contains the number which we want to compute the factorial of
# The return value should be stored in a0
factorial:
# YOUR CODE HERE
addi t1 x0 1 # init t1 = 1
addi t2 a0 0 # init t2 恒等于 n
loop:
blt a0 t1 end # 输入a0若为0或1,直接输出
mul a0 a0 t1 # a0 = t1 * (t1 + 1)
addi t1 t1 1 # t1 = t1 + 1
blt t1 t2 loop
end:
mv a0 a0
# This is how you return from a function. You'll learn more about this later.
# This should be the last line in your program.
jr ra