Skip to main content Link Menu Expand (external link) Document Search Copy Copied

RISC-V Assembly Languague Part 2

Due Mon Sep 23th by 11:59pm in your Project03 GitHub repo

Project03 Interactive Grading will take place on Tuesday Sep 26th.

Exam problems due Wed Sep 25th by 11:59pm in your Project03 GitHub repo

Requirements

  1. You will develop RISC-V assembly language implementations of the following problem and print the results to ensure that both the C implementation and your RISC-V implementation compute the correct answer.
  2. Your executables must be named as follows, and must be compiled with a Makefile
  3. We will test your projects using autograder
  4. Note that in all your programs below you must follow the RISC-V function calling conventions that we cover in class.
  5. Your solutions must follow the logic and implement the same functions as given in the C code.
  6. Remeber to remove the line # YOUR CODE HERE from the starter code.

rstr: Reverse a string

$ ./rstr a
C: a
Asm: a

$ ./rstr FooBar
C: raBooF
Asm: raBooF

$ ./rstr "CS315 Computer Architecture"
C: erutcetihcrA retupmoC 513SC
Asm: erutcetihcrA retupmoC 513SC

rstr_rec: Reverse a string recursively

$ ./rstr_rec a
C: a
Asm: a

$ ./rstr_rec FooBar
C: raBooF
Asm: raBooF

$ ./rstr_rec  "CS315 Computer Architecture"
C: erutcetihcrA retupmoC 513SC
Asm: erutcetihcrA retupmoC 513SC

unstruct: Extract elements of different sizes from a struct and put them into an array of doubles (int64_t):

$ ./unstruct 1 2 3 4 5
C:
1 (0x1)
2 (0x2)
3 (0x3)
4 (0x4)
5 (0x5)
Asm:
1 (0x1)
2 (0x2)
3 (0x3)
4 (0x4)
5 (0x5)

$ ./unstruct 99 -99 99 -99 -99
C:
99 (0x63)
-99 (0xFFFFFFFFFFFFFF9D)
99 (0x63)
-99 (0xFFFFFFFFFFFFFF9D)
-99 (0xFFFFFFFFFFFFFF9D)
Asm:
99 (0x63)
-99 (0xFFFFFFFFFFFFFF9D)
99 (0x63)
-99 (0xFFFFFFFFFFFFFF9D)
-99 (0xFFFFFFFFFFFFFF9D)

findmaxll Find the maximum value in a linked list.

$ ./findmaxll 1 2 3 4 99 5 6 7 8 9
C: 99
Asm: 99

findmaxllp Find the maximum value in a linked list and print the list elements using printf while traversing the list.

$ ./findmaxllp 1 2 3 4 99 5 6 7 8 9
v = 1
v = 2
v = 3
v = 4
v = 99
v = 5
v = 6
v = 7
v = 8
v = 9
C: 99
v = 1
v = 2
v = 3
v = 4
v = 99
v = 5
v = 6
v = 7
v = 8
v = 9
Asm: 99

Exam-like Problems

Put the solutions to the following problems in a file called problems.pdf in your Project03 GitHub Repo. You can typeset your solutions or you can write your solutions by hand and scan or take a photo of your work. Just be sure to put your solution in a single file called problems.pdf.

Question 1 - RISC-V Assembly

Consider the following RISC-V assembly code, then answer the following questions.

.global swap_s
.global sort_s

/* sort_s sorts an array of 32-bit integers in-place,
   in asceding order

   a0 - int arr[]
   a1 - int len

   t0 - int i;
   t1 - int j;

*/

sort_s:
    addi sp, sp, -64
    sd ra, (sp)
    li t0, 1

floop:
    bge t0, a1, fdone
    mv t1, t0

wloop:
    ble t1, zero, wdone
    li t3, 4
    mul t4, t1, t3
    add t5, a0, t4
    addi t6, t5, -4
    lw t5, (t5)
    lw t6, (t6)
    ble t6, t5, wdone

    sd a0, 8(sp)
    sd a1, 16(sp)
    sd t0, 24(sp)
    sd t1, 32(sp)

    mv a1, t1
    addi a2, t1, -1
    call swap_s

    ld a0, 8(sp)
    ld a1, 16(sp)
    ld t0, 24(sp)
    ld t1, 32(sp)

    addi t1, t1, -1
    j wloop

wdone:
    addi t0, t0, 1
    j floop

fdone:
    ld ra, (sp)
    add sp, sp, 64
    ret

Which caller-saved registers are preserved in this function, if any?

Which callee-saved registers are preserved in this function, if any?

Are there caller-saved registers that are used but not preserved? If so, why is this okay?

How many bytes of the stack are actually used by this function?

Does this function use pointer-based array access or indexed-based array access?

Question 2 - C to Assembly

Consider the following C function. Provide and English description of what this function does and provide the RISC-V implementation of this function.

int count_rec_c(char *str, char c) {
    int addval = 0;

    if (str[0] == '\0') {
        return 0;
    } else {
        if (str[0] == c) {
            addval = 1;
        }
        return addval + count_rec_c(&str[1], c);
    }
}

Question 3 - Structs and Assembly

Given what we have learned about how structs are layed out in memory, consider the following struct and answer the following questions.

struct node_st {
    char id[2];
    int value;
    struct node_st *next_p;
};

How many actual bytes will this struct use in memory when considered alignment and padding?

In RISC-V Assembly, how do you load the next_p field value into t0?

Rubric

  1. 80 points: automated test cases
  2. 10 points: interactive grading questions
    1. Design decisions (why did you choose to do it this way?)
    2. Explanation of your implementation (show me how X works?)
    3. Problems encountered and debugged
    4. Single-stepping a program with gdb
  3. 10 points: exam-like problems

Code quality

Points will be deduction if you repo is not clean, that if it contains build artifacts like executables or .o files.

Just like with C code, make sure that you format you Assembly code consistently. Use consistent indentation (spaces not tabs), consistent label formatting, and consistent use of newlines. Points will be deducted for any code quality issues, but any points deducted can be earned back.

Your assembly code must following the logic in the corresponding C code and it must following the register and stack usage convenstions for function calling.