內容目錄

Laboratory 8 – Programming RISC-V

This lab is done individually. V2.

Learning Objectives

  1. Learn the basics of RISC-V assembly code.
  2. Use Linux system calls to print messages and exit.
  3. Write doubly-nested loops in assembly.

Abstract

In this lab, you will write assembly code with increasing complexity.

Equipment

You will use your computer and program on the cpen211-ssh RISC-V compute servers.
You may wish to consult the RISC-V Instruction Set Summary (1 page) or (4 page)
versions.

Overview

There are 4 parts to this lab:

  • A) Hello World
  • B) Rectangles
  • C) Triangles
  • D) Subroutines

Each part requires adding complexity to your program.

A. Hello World

  1. Go back and repeat Lab 0 Part 1 again. It should make a lot more sense now!
    • Do both the C and Assembly parts.
  2. Dig deeper on the assembly language part until you can confidently answer the following questions:
    • How does the processor know where to start executing the program?
    • How does the program let the processor know it exit the program? What would happen if this wasn’t done?
    • What is the purpose of the .equ lines ?
    • What is the purpose of the .ascii line?
    • List all of the labels used in this program.
    • What happens when you delete the two characters `\n’ at the end of the
      string? Hint: don’t forget to change the string length (unlike C, strings in
      assembly are not null-terminated by default.) These two characters
      represent a single, non-printable ASCII character – what is the decimal and
      hexadecimal value of this non-printable character?
    • In Lab 0, you were asked to print a second (different) message after the first
      message. Many of you skipped this step – make sure you do it this time!

B. Rectangle

  1. Make a copy of hello.s, and call it rect.s, eg in Linux type:
    cp hello.s rect.s

  2. In the steps below, modify rect.s incrementally to build up your solution. It is
    strongly advised you do not skip ahead and go to the last part, or you will find
    debugging very challenging.

    • Don’t forget to use the “gdb” program to help you debug!
  3. Print an asterisk “*” and a new line “\n”.

    • Modify the program so you print a single asterisk character “*”, then print
      a newline character “\n”, then exit.

    • Make sure your program works before going to the next step.

  4. Print N asterisk characters ending with a new line.

    • Define a constant N using “.equ” with a small value like 3 or 4.

    • Use a loop, storing the loop count and the loop end value in the t registers.

    • Change the value of N. Make sure your program works for N=0 to 10. When
      N=0, no stars should print and no newline should print.

  5. Print N lines of text, where each line has N asterisks ending with a new line.

    • Add another loop outside of the loop in step 6, using more t registers.

    • Change the value of N. Make sure your program works for N=0 to 10. When
      N=0, no stars should print and no newline should print.

C. Triangles

  1. Make a copy of rect.s and call it tri.s

  2. Assuming the outer loop is Y=1..N (or 0..N-1, whichever you prefer), and the inner
    loop is X=1..N (likewise, 0..N-1 is ok), modify the inner loop X so that it only prints
    up to Y stars, that is X=1..Y. This should print a simple right-angle triangle where
    the diagonal is exactly 45 degrees.

    • Don’t forget to use the “gdb” program to help you debug!
  3. Modify the loop structure of your assembly code to match the C code below. (NOTE: do NOT simply write the C code version and compile it.) In this implementation, you will define two constants NY and NX which define the number of lines of text (NY) and the number of asterisks to print (NX) at the base of the triangle when Y=NY.

    void tri( int NX, int NY )
    {
        int x_max = NX;
        for( int y=0; y < NY; y++ ) {
            for( int x=0; x < x_max; x += NY ) {
            printf("*");
            }
            printf("\n");
            x_max += NX;
        }
    }
    • Running tri(4,8), where NX=4 and NY=8, should print this:

      *
      *
      **
      **
      ***
      ***
      ****
      ****
    • Running tri(8,4), where NX=8 and NY=4, should print this:

      **
      ****
      ******
      ********
  4. Test your program with a variety of values for NX and NY.

D. Subroutines

  1. Divide your program into a main part, and a subroutine for tri(). Pass the values NX
    and NY as arguments in a0 and a1, respectively. The main part should only set up
    the arguments, call tri(), and then exit. Note: you can rely upon the value of the
    stack pointer (sp) being set up for you automatically by the compilation system.
  2. Change your main part to call tri() twice before exiting, eg: tri(5,10) and tri(20,10).

SUBMISSION REQUIREMENTS

  1. TBD
最後修改日期: 2025 年 11 月 4 日

作者

留言

撰寫回覆或留言

發佈留言必須填寫的電子郵件地址不會公開。