Due 11:55pm on Wednesday, October 9.
For this exercise, you will download the MARS assembler, and run a few simple MIPS assembly programs from the course website.
First, download MARS using the link on the course website, under "Reference Materials (for Labs)". Launch it by double-clicking the .jar file. You may be prompted to install Java runtime environment if your computer does not already have it installed. Familiarize yourself with the menu.
Configure it as follows: Settings->Permit extended (pseudo) instructions and formats” is enabled, and Settings->Memory Configuration->Compact, Data at Address 0 is selected. The first setting allows us to use pseudo-instructions when convenient, and the second setting tells the assembler where it can expect to place data and code in memory.
Download three assembly files from the course website:
Use the File->Open menu to open one of these programs. Assemble (i.e., compile) the program by hitting Run->Assemble, or by hitting the screwdriver/wrench icon, or by pressing F3. Run the program by hitting Run->Go, or by hitting the icon with the play button. You may single-step through the program by hitting Run->Step, or hitting the icon with the '1' to the right of the play button. You can also set one or more breakpoints by checking the box to the left of the instructions where you want execution to break, and then hit Run.
The bottom pane has two tabs: MARS Messages shows errors or warnings during assembly; Run I/O is the input/output.
Run each of the three programs. Make sure you understand every single line of code. Here is what to expect for each:
There are several library routines provided by MARS that an assembly program can use. These are called system calls, or syscall. These services include support for printing integers and strings (similar to the printf() function in C), reading integers and strings from the keyboard (similar to scanf() in C), memory allocation (similar to malloc() in C), exiting from a program (similar to return from main() in C), etc.
An assembly program accesses those services using the syscall command. There is only one syscall command for all these services, but which service is requested is determined by the values provided in certain registers. The value in register $v0 determines which service is requested, and often parameters are passed to the service using registers $a0, $a1, $a2 and $a3. If a value needs to be returned to the program (e.g., reading an integer from keyboard), it is typically returned in register $v0.
For a full listing of system calls available in MARS, please refer to http://courses.missouristate.edu/kenvollmar/mars/help/syscallhelp.html. We will mostly be using system calls numbered 1 to 17.
For example, to exit a program, you would use syscall with 10 in $v0:
addi $v0, $0, 10 # system call 10 for exit syscall # exit the program
Sometimes the instruction addi $v0, $0, 10 is shortened to the more readable pseudo-instruction li $v0, 10, which stands for ("load the immediate value 10 into $v0").
As another example, suppose you want to print a string labeled myString. Remember that myString is simply a location in memory starting where the contents of the string are stored. You would use syscall with 4 in $v0 for printing strings. This system call expects the register $a0 to contain the address of the starting memory location where the string is stored. An easy way to put that address in register $a0 is to use the la pseudo-instruction. It stands for "load the address of". Here is a code fragment that prints the string labeled myString:
li $v0, 4 # system call 4 for printing a string la $a0, myString # put the address of string in $a0 syscall # print the string
Study all of the system calls from 1 to 17.
You are given a program in MIPS assembly language that computes the area of a rectangle given the width and the height (ex1.asm). The width and height are read from the standard input after prompting the user, and then the program computes the area and prints it on the standard output. Here's an example scenario:
Enter width (integer):
2
Enter height (integer):
4
Rectangle's area is 8
Modify the program so that it also calculates and prints the perimeter (i.e., sum of all sides) of the rectangle. Thus, after modification, the example scenario would become:
Enter width (integer):
2
Enter height (integer):
4
Rectangle's area is 8
Its perimeter is 12
Test your program in MARS on a few different inputs to verify that it is working correctly. You can simply enter the inputs within the MARS "Run I/O" window. Once you are satisfied that the program is working fine within MARS, follow the directions at the bottom of this page to copy it to the comp411-2fa19.cs.unc.edu server, and then run the self-checking script. Make sure that the program passes the self-checker. If you see errors, you can open the program in pico and edit on the server, or you can edit on the laptop and then copy again to the server. When you are done with all the exercises, submit your work via Sakai according to instructions at the bottom of this page.
Copy the file ex1.asm to ex2.asm. Modify the program in ex2.asm to make it work on multiple inputs. In particular, it should repeatedly ask for width and height values, and print the corresponding area and perimeter, until the user enters the value 0 for width. At that point, the program should terminate. Here's an execution scenario:
Enter width (integer):
2
Enter height (integer):
4
Rectangle's area is 8
Its perimeter is 12
Enter width (integer):
5
Enter height (integer):
6
Rectangle's area is 30
Its perimeter is 22
Enter width (integer):
0
Essentially, this exercise involves introducing a loop around the main code of Exercise 1. As long as width is not equal to 0, the program repeats by looping back to the top of the loop. If width is 0, the program breaks out of the loop. The key instructions for forming such loops are: beq, bne and j. You may need one or more of these, depending on how you construct your loop.
Test your program in MARS, and once you are satisfied that it is working properly, follow the directions at the bottom of this page to copy the program to the server, then run the self-checking script, and finally submit your work via Sakai.
For this exercise, you are to write an assembly program to convert red-green-blue (RGB) values for a set of pixels into a single gray value per pixel. First, study the C version of the program (ex3.c), and compile and run it. Your task is to convert this C program into an equivalent MIPS assembly program.
For writing the MIPS assembly version, use the starter file ex3.asm. Your code must strictly follow these specifications:
You are given an array called pixels, each element of which is a 32-bit word representing a color value. The lowest significant 8 bits of each color value denote an unsigned integer (from 0 to 255) representing the color's "blue" value, the next 8 bits are the "green" value, the next 8 bits are the "red" value, and the most significant 8 bits are all zeroes. For example, the pixel with value 0x0001ff22 has color components: red = 1 (or 0x01), green = 255 (or 0xff), blue = 34 or (0x22).
For this programming assignment, you will read through this array of pixels, and for each pixel, convert the color pixel into a grayscale pixel using a simple formula: gray value = (red + green + blue) / 3. Note the division is integer divide and truncate (i.e., no rounding needed). For the above example, the gray value would be (1+255+34) / 3 or 96.
The calculation of the gray value should be done in a separate procedure called rgb_to_gray. (Note: For this simple task, there is no need to create and use a stack. This is because there are no nested procedure calls, and the calculation is fairly trivial, so no sophisticated management of register saves/restores is needed.) We simply use the jal instruction to call a procedure, and the jr instruction to return from that procedure.
After calculating the gray value for a pixel, print it out to the console (only one element per line). The program keeps reading RGB values and printing the corresponding gray value, until it encounters an input of -1. The expected output format is given in the comments in the starter file on the course website.
Hint: Study and understand the divide instruction thoroughly before attempting to use it!
Name the file containing your code ex3.asm. Assemble and run your program in MARS, and make sure it produces the correct output (see near the top of the starter file). You do not need to enter any inputs; all the data is embedded within the program in an array called pixels.
Your assignment must be submitted electronically via Sakai by 11:55pm on Wednesday, October 9. You will submit your work on Exercises 1-3, specifically, the files ex1.asm, ex2.asm and ex3.asm.
Sample Inputs/Outputs: Sample input and output files are provided for Exercises 1 and 2 on the comp411-2fa19.cs.unc.edu server at /home/students/montek/comp411/samples/lab6. There is no input file needed for Exercise 3; the input data is embedded within the assembly file. The expected output for Exercise 3 is available under the sample folder, but it is also specified as a comment at the top of the provided assembly file.
Testing: You will be running MARS on your laptop, and all assembly code development and testing will be done in MARS. For this lab, you will provide the input to your program manually by typing it within the MARS "Run I/O" window. The input files are relatively small, so you can simply type their contents into MARS. (You can also open the input files in pico within a terminal window, and try cut-and-paste between pico/terminal and MARS, but sometimes MARS does not handle pasted text properly and crashes.)
Self-checking Script: Once you are satisfied that your assembly programs are running fine within MARS on your laptop, it would be best to copy those files over to the server so you can run the self-checking script to be doubly sure that your results are correct. (Our self-checking scripts are only written to run on the server.) Copy the files ex1.asm, ex2.asm and ex3.asm to the server under the appropriate folder in your home directory (e.g., comp411lab/lab6). Then run the self-checking script:
% cd ~/comp411lab/lab6
% cp /home/students/montek/comp411/samples/lab6/* .
% selfchecklab6
How to submit: If you made final edits to your assembly programs on the server, first transfer your work back to your laptop. Next, log in to Sakai in a browser window, and look for the lab under "Assignments" in the left panel. Attach the requested files and submit.
In case of any problems, please contact the instructor or the TAs.