CS61C(su20) lab03

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

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

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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值