wys的个人博客

你有很多事放不下?做人要潇洒一点~

0%

cs61c_lab3

cs61c_lab3

Exercise 1: Familiarizing yourself with Venus

  1. .data 指令用于指定程序中数据段的开始。在这个部分中,可以定义程序将使用的变量和数据。.word 指令用于在 .data 部分内分配空间并初始化数据值。.text 指令用于指定程序的代码或文本段的开始。
  2. 最后输出结果是34,表示斐波那契数列的第九项。
  3. n的地址是0x10000008
  4. 在运行过程中把t3改为0x0000000D

题外话:我网上查到说ecall的调用号应该在a7,但是这个代码里的调用号不知道为什么在a0,可能是cs61c自己开发的这个Venus模拟器的问题。

Exercise 2: Translating from C to RISC-V

  1. 表示变量k的寄存器应该是t0.

  2. 表示变量k的寄存器应该是s0.

  3. 表示source的指针寄存器是s1,表示dest数组的指针寄存器是s2

  4. loop和square中的代码汇编代码为c 中循环中的代码

  5. 通过地址寻址的方式来操作指针。

Exercise 3: Factorial

这道题的代码写了两个版本,第一个版本是循环的写法,第二个版本是递归的写法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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

代码如下

~~~assembly .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, '' # 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