cs61c_lab3
Exercise 1: Familiarizing yourself with Venus
.data
指令用于指定程序中数据段的开始。在这个部分中,可以定义程序将使用的变量和数据。.word
指令用于在.data
部分内分配空间并初始化数据值。.text
指令用于指定程序的代码或文本段的开始。- 最后输出结果是34,表示斐波那契数列的第九项。
- n的地址是0x10000008
- 在运行过程中把t3改为0x0000000D
题外话:我网上查到说ecall的调用号应该在a7,但是这个代码里的调用号不知道为什么在a0,可能是cs61c自己开发的这个Venus模拟器的问题。
Exercise 2: Translating from C to RISC-V
-
表示变量k的寄存器应该是t0.
-
表示变量k的寄存器应该是s0.
-
表示source的指针寄存器是s1,表示dest数组的指针寄存器是s2
-
loop和square中的代码汇编代码为c 中循环中的代码
-
通过地址寻址的方式来操作指针。
Exercise 3: Factorial
这道题的代码写了两个版本,第一个版本是循环的写法,第二个版本是递归的写法
factorial:
# YOUR CODE HERE
# VERSION 1
# add t1, a0, x0
# addi t1, t1, -1
# Loop:
# beq t1, x0, Exit_factorial
# mul a0, a0, t1
# addi t1, t1, -1
# jal x0, Loop
# Exit_factorial:
# jr ra
# VERSION 2
addi t1, x0, 1
beq t1, a0, Exit_factorial
addi sp, sp, -8
sw ra 4(sp)
sw a0 0(sp)
addi a0, a0, -1
jal ra factorial
lw t0 0(sp)
lw ra 4(sp)
mul a0, t0, a0
addi sp, sp, 8
Exit_factorial:
jr ra
Exercise 4: RISC-V function calling with map
代码如下
.globl map
.text
main:
jal ra, create_default_list
add s0, a0, x0 # a0 = s0 is head of node list
#print the list
add a0, s0, x0
jal ra, print_list
# print a newline
jal ra, print_newline
# load your args
add a0, s0, x0 # load the address of the first node into a0
# load the address of the function in question into a1 (check out la on the green sheet)
### YOUR CODE HERE ###
la a1 square
# issue the call to map
jal ra, map
# print the list
add a0, s0, x0
jal ra, print_list
# print another newline
jal ra, print_newline
addi a0, x0, 10
ecall #Terminate the program
map:
### YOUR CODE HERE ###
addi sp, sp, -12
sw ra, 0(sp)
sw s0, 4(sp)
sw s1, 8(sp)
beq a0, x0, done # If we were given a null pointer (address 0), we're done.
add s0, a0, x0 # Save address of this node in s0
add s1, a1, x0 # Save address of function in s1
lw a0 0(s0)
jalr s1
sw a0 0(s0)
lw a0 4(s0)
add a1 s1 x0 #事实上我把这行注释了也没问题
# recurse
jal ra, map
done:
# Epilogue: Restore register values and free space from the stack
lw ra, 0(sp)
lw s0, 4(sp)
lw s1, 8(sp)
addi sp, sp, 12
jr ra # Return to caller
square:
mul a0 ,a0, a0
jr ra
create_default_list:
addi sp, sp, -12
sw ra, 0(sp)
sw s0, 4(sp)
sw s1, 8(sp)
li s0, 0 # pointer to the last node we handled
li s1, 0 # number of nodes handled
loop: #do...
li a0, 8
jal ra, malloc # get memory for the next node
sw s1, 0(a0) # node->value = i
sw s0, 4(a0) # node->next = last
add s0, a0, x0 # last = node
addi s1, s1, 1 # i++
addi t0, x0, 10
bne s1, t0, loop # ... while i!= 10
lw ra, 0(sp)
lw s0, 4(sp)
lw s1, 8(sp)
addi sp, sp, 12
jr ra
print_list:
bne a0, x0, printMeAndRecurse
jr ra # nothing to print
printMeAndRecurse:
add t0, a0, x0 # t0 gets current node address
lw a1, 0(t0) # a1 gets value in current node
addi a0, x0, 1 # prepare for print integer ecall
ecall
addi a1, x0, ' ' # a0 gets address of string containing space
addi a0, x0, 11 # prepare for print string syscall
ecall
lw a0, 4(t0) # a0 gets address of next node
jal x0, print_list # recurse. We don't have to use jal because we already have where we want to return to in ra
print_newline:
addi a1, x0, '\n' # Load in ascii code for newline
addi a0, x0, 11
ecall
jr ra
malloc:
addi a1, a0, 0
addi a0, x0 9
ecall
jr ra