CMPT 215: Introduction to Computer Organization and Architecture

Hello, if you have any need, please feel free to consult us, this is my wechat: wx91due

CMPT 215: Introduction to Computer Organization and Architecture
Lab 2: Introduction to RISC-V assembly
January 15, 2024

RISC-V Toolchain & QEMU
During this course, you will be writing shortassembly programs in RISC-V assembly lan- guage. A toolchain for compiling/assembling/linking/debugging RISC-V code has been built and made available on the lab computers and the tuxworld computers. After building your code, you can use QEMU (also available on tuxworld and lab computers) to emulate a RISC-V system and run your programs.
1 Introduction

We will first start by introducing some basics and setting up your git repository, then con- tinuing with the main programming task. If you h term, you can skip ahead to Section 2

As you make progress, make sure you understand the steps you are doing and ask your TA if you have any questions. It is highly advisable to complete this lab during your lab section.

1.1 Accessing the department’s Linux computers

1.1.1 Access using a department computer

If you are using a campus Linux computer (a lab computer in Spinks S311 or S320, or the Spinks open lab),
1. You need to make sure you are booted into Linux (if you are looking at a Windows system, you need to restart the computer and choose
2. The next step is to open a terminal. You can do so simply by using the ‘super’ key on your keyboard (usually the key with the ‘Windows’ icon on it) and type the word “terminal”. You should see one or more matches. Any option is fine.
1.1.2 Access using an off-campus or personal computer
If you are using an off-campus computer, you will need to ssh into tuxworld. To do so, you need to open a terminal (or ‘command prompt’ on Windows), and ty
ssh abc123@tuxworld. usask. ca
You should then type your password (it’s okay that you don’t see any characters being typed on the screen) and hit enter.
1.2 You are in!
You should now be at a terminal (remote or on a lab computer) and ready to go! If you are having difficulty reaching this point, ask your TA for help.
1.3 Using the terminal
The terminal prompt will look something like this,
user@machine ~ $
To exit your terminal (or ssh connection), you can simply type
$ exit
1.4 Creating (or finding) your SSH key
The next step is to create (or find) your SSH key using the following command (if you are curious how this command works, by the end of the term you will be able to understand and put together commands like this!) $ cd ~ && ls .ssh/id_rsa.pub > /dev/null 2>&1 && echo "Found" || echo "Not found"
If the previous command shows the message ”Found”, you can skip to Section 1.5 (because you already have an SSH key). Otherwise, you will have to create a new key using the command ssh-keygen.
$ ssh-keygen
When prompted for the path to save the key, don’t type anything and hit ‘enter’ . When prompted to set a passphrase, it is recommended to not type anything and hit ‘enter’ .
1.5 Getting your SSH key
You should now have your SSH key. You can view your public SSH key using the command,
$ cat ~/. ssh/id_rsa. pub
The output of the previous command should look similar to this,
ssh-rsa
AAAAB3NzaC1yc2EAAAADAQABAAABgQDXIN8AFqXEsU+uPktz2a97kDmnNgnCV1qScsxYCJ86 JksnzswEHiK8x/Fr20xIpnJNW6EXsUCgoMac
user@machine
Do not close your terminal. You are going to need this key for the following step. If you are having difficulty reaching this point, ask your TA for help.
1.6 Adding your public SSH key to GitLab

1. Go to https://git.cs.usask.ca using an internet browser. This is the department’s GitLab server.

2. Log on using your NSID and password.

3. In the top left corner you should see something that looks like this

4. Click on your user image to open the following menu

5. Click on “Preferences”, then choose the “SSH Keys” submenu from the left side bar. 

6. On the right you should find an “Add new key” button.

7. In the “Key” text box, copy and paste (copying from- and pasting to the terminal is done by using ctrl+shift+c and ctrl+shift+v) the public SSH key that is displayed on your terminal.

8. Click the “Add key” button

1.7 Setting your username and email
We will now set up your username and email as follows:
$ git config --global user. name "Jane Smith"
$ git config --global user. email "abc123@usask. ca"
Replace “Jane Smith” with you actual full name, and “abc123” with your actual NSID.
2 Cloning your git repository
A Git repository has been already created for you, and you should be able to have access to it. If you have never logged onto https://git.cs.usask.ca, your repository should be created approximately 5 minutes (while our script finds you and creates the repository for you) after you have logged You can clone your repository using the following commands (replacing ‘abc123’ with your actual NSID):
$ git clone git@git. cs.usask. ca:cmpt215-winter2024/abc123.git cmpt215 $ cd cmpt215
$ echo abc123 > nsid. txt
$ git add .
$ git commit -m "initial commit"
$ git push --set-upstream origin master
If you see a warning that you are cloning an empty repository, this is completely fine. If you are having difficulty reaching this point, ask your TA for help.
3 Hello RISC-V!
3.1 Source code
Using your favourite text editor, type in the following program into a file named hello world. s . Don’t forget to do git add and git commit after writing your code.
1 # function numbers for environment calls
2 .equ SYS_exit, 93
3 .equ SYS_printStr, 248
4
5 # read-only data section
6 .section .rodata
7 str:
8 .string "Hello World! "
9
10 # code section
11 .section .text
12 .globl _start
13 _start:
14 la a0 , str # print string
15 li a7 , SYS_printStr
16 ecall
17
18 li a0, 0 # exit(0)
19 li a7 , SYS_exit
20 ecall

Lines 2 and 3 use the .equ directive to tell the assembler about some constants and gives names to them. This is analog to the #define statement in C.

Line 6 is an assembler directive that tells the assembler that the following is to be stored in the “rodata section” (read only data) of the program. Line 7 is a label that takes the value of the current address in the rodata segment. Line 8 is another assembler dterminated string (an ascii string terminated with a zero or null byte). The address str is the address of the first byte of the string.

Line 11 is another assembler directive that tells the assembler that the following is to be stored in the “text section” (code section) of the program.

Line 12 makes the start symbol global for linking. The code section starts at start which is another label (that points to the first byte of the following la instruction).

Line 14 loads the address str into register a0. Line 15 loads the immediate (constant) value corresponding to SYS printStr into register a7. Line 16 is that performs some function indicated by the function code in register a7, and takes its arguments through one or more of the ‘a’ registers. Lines 18 through 20 perform another environment call that terminates the program.
3.2 Makefile
Copy the starter Makefile from /student/cmpt215/starter/lab2/Makefile to yourcmpt215 directory and make any necessary edits. The TOOLCHAIN PATH should be set to the path of the RISC-V toolchain which is located under /usr/local/riscvmulti/bin. The linking rule (line 40) should also be completed to link all object files and libraries (in this case we have just the one object file, hello world.o, which will be created under build/qemu-riscv32) and create the hello world binary.
If you have any questions, make sure to ask your TA.
3.3 BASH script to run/debug our RISC-V programs
In this section you will write a short BASH script called run (without a . sh suffix) to allow you to quickly launch and debug your RISC-V programs. We can do so by using the RISC-V QEMU emulator located at /student/cmpt215/qemu/bin/qemu-riscv32 .
To run your program,
$ /student/cmpt215/qemu/bin/qemu-riscv32 <binary>
where <binary> is the binary that you obtained by running make.
To debug your program,
Terminal 1
$ /student/cmpt215/qemu/bin/qemu-riscv32 -g <port_num> <binary>
Terminal 2
$ /usr/local/riscvmulti/bin/riscv64-unknown-elf-gdb <binary> where <binary> is the binary that you obtained by running make, and port num is a port number between 30000 and 40000 that allows gd
Terminal 2 to connect to the QEMU process running in Terminal 1.
To simplify the above process, you will write a BASH script that takes two command-line arguments:
(1) the mode argument, and (2) the pathname of a RISC-V binary. The mode argument can be one of --qemu, --qemu-gdb, or --gdb.
In --qemu mode, the script will simply run QEMU:
/student/cmpt215/qemu/bin/qemu-riscv32 <binary>
In --qemu-gdb mode, the script will run QEMU in debugging mode using the -g option and some random port number between 30000 and 40000 (hint: you can randomize your port choice by using ✩((30000 + ✩RANDOM % 10000))):
/student/cmpt215/qemu/bin/qemu-riscv32 -g <port_num> <binary>
Make sure to echo the port number before you run QEMU.
In --gdb mode, the script will run gdb:
/usr/local/riscvmulti/bin/riscv64-unknown-elf-gdb <binary>
Don’t forget to chmod +x you BASH script and add the shebang line #!/bin/bash at the beginning of the script.
If you have any questions, make sure to ask your TA.
4 Debugging with GDB & QEMU
Copy the starter file /student/cmpt215/starter/lab2/strlen.s to your cmpt215 direc- tory and modify the Makefile to also build the strlen bin
Once the strlen binary is built, try to run the program using
$ ./run --qemu strlen
This program is supposed to read a string (max 100 characters) and display its length. You will notice that the program causes a segmentatio
In one terminal run the program again using --qemu-gdb mode:
$ ./run --qemu-gdb strlen
In another terminal (it is preferable to have both terminals on the same lab/tux computer; it can work across different machines but it’s som
$ ./run --gdb strlen
GNU gdb (GDB) 13.2
.
.
.
Reading symbols from strlen . . .
(gdb) target remote <hostname>:<port>
Remote debugging using <hostname>:<port>
_start () at strlen. s:26
26 la a0, prompt # print prompt string (gdb) c
Continuing .

The target remote command allows you to connect to the QEMU process running in Ter- minal 1. Your script should echo the randomized the first instruction at start. Use c or continue to allow the program to run.gdb will catch the segmentation fault, but this doesn’t tell us much on its own. Run the program again and set up a breakpoint using b <line num> or break <line num> (e.g., line 37) to step through the loop.

One the breakpoint is reached, execution will pause and you can use n or next to step through the instructions. info registers will show you register values.

Once you find and fix the error, the program should correctly output the length of the string (including the newline character at the end of your input).

发表评论

电子邮件地址不会被公开。 必填项已用*标注