Week 04 Laboratory Exercises

Objectives

  • understanding how array indices are calculated
  • practicing using MIPS control instructions (branch)
  • learning how MIPS memory access works (lw/sw)
  • practicing running MIPS programs with mipsy, mipsy-web, spim, or qtspim

Preparation

Before the lab you should re-read the relevant lecture slides and their accompanying examples.

Getting Started

Set up for the lab by creating a new directory called lab04 and changing to this directory.
mkdir lab04
cd lab04

There are some provided files for this lab which you can fetch with this command:

1092 fetch lab04

If you're not working at CSE, you can download the provided files as a zip file or a tar file.

Exercise — individual:
Bigger MIPS

In the files for this lab, you have been given print_bigger.s, a MIPS assembler program that reads 10 numbers and then prints them:

cat numbers1.txt
12086
24363
47363
64268
34001
6800
60742
48867
26002
54999
1092 mipsy print_bigger.s <numbers1.txt
12086
24363
47363
64268
34001
6800
60742
48867
26002
54999

Add code to print_bigger.s to make it equivalent to this C program:

// Read 10 numbers into an array then print the numbers which are
// larger than the final number read.

#include <stdio.h>

#define ARRAY_LEN 10

int main(void) {
    int i, final_number;
    int numbers[ARRAY_LEN] = { 0 };

    i = 0;
    while (i < ARRAY_LEN) {
        scanf("%d", &numbers[i]);
        final_number = numbers[i];
        i++;
    }
    i = 0;
    while (i < ARRAY_LEN) {
        if (numbers[i] >= final_number) {
            printf("%d\n", numbers[i]);
        }
        i++;
    }
}

For example:

1092 mipsy print_bigger.s <numbers1.txt
64268
60742
54999
cat numbers2.txt
53906
9064
40906
4504
4774
7892
15334
45515
55387
5681
1092 mipsy print_bigger.s <numbers2.txt
53906
9064
40906
7892
15334
45515
55387
5681

When you think your program is working, you can use autotest to run some simple automated tests:

1092 autotest print_bigger 

When you are finished working on this exercise, you must submit your work by running give:

give dp1092 lab04_print_bigger print_bigger.s

You must run give before Monday 01 January 00:00 (midnight) (Saturday 01 January 00:00) to obtain the marks for this lab exercise. Note that this is an individual exercise, the work you submit with give must be entirely your own.

Exercise — individual:
MIPS Order Checking

In the files for this lab, you have been given unordered.s, a MIPS assembler program that reads 10 numbers and then prints 42:

Add code to unordered.s to make it equivalent to this C program:

// Read 10 numbers into an array
// print 0 if they are in non-decreasing order
// print 1 otherwise

#include <stdio.h>

#define ARRAY_LEN 10

int main(void) {
    int i;
    int numbers[ARRAY_LEN] = { 0 };

    i = 0;
    while (i < ARRAY_LEN) {
        scanf("%d", &numbers[i]);
        i++;
    }

    int swapped = 0;
    i = 1;
    while (i < ARRAY_LEN) {
        int x = numbers[i];
        int y = numbers[i - 1];
        if (x < y) {
            swapped = 1;
        }
        i++;
    }

    printf("%d\n", swapped);
}

For example:

cat numbers1.txt
12086
24363
47363
64268
34001
6800
60742
48867
26002
54999
1092 mipsy unordered.s <numbers1.txt
1
cat sorted.txt
1
2
3
4
5
6
7
8
9
10
1092 mipsy unordered.s <sorted.txt
0

When you think your program is working, you can use autotest to run some simple automated tests:

1092 autotest unordered 

When you are finished working on this exercise, you must submit your work by running give:

give dp1092 lab04_unordered unordered.s

You must run give before Monday 01 January 00:00 (midnight) (Saturday 01 January 00:00) to obtain the marks for this lab exercise. Note that this is an individual exercise, the work you submit with give must be entirely your own.

Exercise — individual:
MIPS Swapping

In the files for this lab, you have been given swap_numbers.s, a MIPS assembler program that reads 10 numbers and then prints them:

Add code to swap_numbers.s to make it equivalent to this C program:

// Read 10 numbers into an array
// swap any pair of numbers which are out of order
// then print the array

#include <stdio.h>

#define ARRAY_LEN 10

int main(void) {
    int i;
    int numbers[ARRAY_LEN] = { 0 };

    i = 0;
    while (i < ARRAY_LEN) {
        scanf("%d", &numbers[i]);
        i++;
    }

    i = 1;
    while (i < ARRAY_LEN) {
        int x = numbers[i];
        int y = numbers[i - 1];
        if (x < y) {
            numbers[i] = y;
            numbers[i - 1] = x;
        }
        i++;
    }

    i = 0;
    while (i < ARRAY_LEN) {
        printf("%d\n", numbers[i]);
        i++;
    }
}

For example:

1092 mipsy swap_numbers.s <numbers1.txt
12086
24363
47363
34001
6800
60742
48867
26002
54999
64268
1092 mipsy swap_numbers.s <numbers2.txt
9064
40906
4504
4774
7892
15334
45515
53906
5681
55387

When you think your program is working, you can use autotest to run some simple automated tests:

1092 autotest swap_numbers 

When you are finished working on this exercise, you must submit your work by running give:

give dp1092 lab04_swap_numbers swap_numbers.s

You must run give before Monday 01 January 00:00 (midnight) (Saturday 01 January 00:00) to obtain the marks for this lab exercise. Note that this is an individual exercise, the work you submit with give must be entirely your own.

Challenge Exercise — individual:
MIPS Bubbles

In the files for this lab, you have been given bubblesort.s, a MIPS assembler program that reads 10 numbers and then prints them:

Add code to bubblesort.s to make it equivalent to this C program:

// Reads 10 numbers into an array, bubblesorts them
// and then prints the 10 numbers
// then print them

#include <stdio.h>

#define ARRAY_LEN 10

int main(void) {
    int i;
    int numbers[ARRAY_LEN] = { 0 };

    i = 0;
    while (i < ARRAY_LEN) {
        scanf("%d", &numbers[i]);
        i++;
    }

    int swapped = 1;
    while (swapped) {
        swapped = 0;
        i = 1;
        while (i < ARRAY_LEN) {
            int x = numbers[i];
            int y = numbers[i - 1];
            if (x < y) {
                numbers[i] = y;
                numbers[i - 1] = x;
                swapped = 1;
            }
            i++;
        }
    }

    i = 0;
    while (i < ARRAY_LEN) {
        printf("%d\n", numbers[i]);
        i++;
    }
}

For example:

1092 mipsy bubblesort.s <numbers1.txt
6800
12086
24363
26002
34001
47363
48867
54999
60742
64268
1092 mipsy bubblesort.s <numbers2.txt
4504
4774
5681
7892
9064
15334
40906
45515
53906
55387

When you think your program is working, you can use autotest to run some simple automated tests:

1092 autotest bubblesort 

When you are finished working on this exercise, you must submit your work by running give:

give dp1092 lab04_bubblesort bubblesort.s

You must run give before Monday 01 January 00:00 (midnight) (Saturday 01 January 00:00) to obtain the marks for this lab exercise. Note that this is an individual exercise, the work you submit with give must be entirely your own.

Challenge Exercise — individual:
MIPS NUXI

We have two 32 bit values which the bytes have placed in an unknown order.

Fortunately we know the 4 bytes of the first value originally contained the ASCII values "UNIX", and the two values were shuffled in an identical manner.

e.g. if the first value was "IXUN", and the second value was "PSMI", then the second value correctly ordered would be "MIPS".

Write a MIPS program nuxi.s which read the two values and prints the second value with its bytes correctly ordered.

For example:

1092 mipsy nuxi.s
1481199189
-2023406815
-2023406815
1092 mipsy nuxi.s
1431193944
-2023406815
558065031
1092 mipsy nuxi.s
1230525774
-559038737
-1377898562
1092 mipsy nuxi.s
1229871189
305419896
1444033656

When you think your program is working, you can use autotest to run some simple automated tests:

1092 autotest nuxi 

When you are finished working on this exercise, you must submit your work by running give:

give dp1092 lab04_nuxi nuxi.s

You must run give before Monday 01 January 00:00 (midnight) (Saturday 01 January 00:00) to obtain the marks for this lab exercise. Note that this is an individual exercise, the work you submit with give must be entirely your own.

Challenge Exercise — individual:
Read & Execute MIPS Instructions

Write a MIPS assembler program dynamic_load.s which reads MIPS instructions as signed decimal integers until it reads the value -1, then executes the instructions.

dynamic_load.s should read instructions until it reads the value -1.

dynamic_load.s should then print a message, load the instructions, print another message, exactly as in the examples below.

For example, below is a tiny MIPS assembler program which prints 42. The comment on each line shows how the instruction is encoded, as a hexadecimal and as a signed decimal integer; it is this signed integer value that your program will read.

li $a0, 42  # 3404002a    872677418
li $v0, 1   # 34020001    872546305
syscall     # 0000000c           12
jr $ra      # 03e00008     65011720

This is what dynamic_load.s must do.

1092 mipsy dynamic_load.s
Enter mips instructions as integers, -1 to finish:
872677418
872546305
12
65011720
-1
Starting executing instructions
42Finished executing instructions

The supplied files for the lab include files containing the instructions for some MIPS assembler programs from lectures. You can use these to test your program; for example:

cat add.instructions
872939537
873005081
19419168
663585
872546305
12
872677386
872546315
12
65011720
-1
1092 mipsy dynamic_load.s <add.instructions
Enter mips instructions as integers, -1 to finish:
Starting executing instructions
42
Finished executing instructions
1092 mipsy dynamic_load.s <print10.instructions
Enter mips instructions as integers, -1 to finish:
Starting executing instructions
1
2
3
4
5
6
7
8
9
10
Finished executing instructions
1092 mipsy dynamic_load.s <sum_100_squares.instructions
Enter mips instructions as integers, -1 to finish:
Starting executing instructions
338350
Finished executing instructions

If you want to experiment with your own tests, this command will give you any MIPS program as integers.

1092 mips_instructions 42.s
537133098
537001985
12
537133066
537001995
12
65011720
-1

If you want to try creating your own test cases, here is some MIPS assembler that prints a message without using initialized data:

# print a string without using pre-initialized data
# for the dynamic load challenge exercise

main:
    li   $a0, 'H'       # printf("%c", 'Hi');
    li   $v0, 11
    syscall

    li   $a0, 'i'       # printf("%c", 'i');
    li   $v0, 11
    syscall

    li   $a0, '\n'      # printf("%c", '\n');
    li   $v0, 11
    syscall

    jr   $ra

When you think your program is working, you can use autotest to run some simple automated tests:

1092 autotest dynamic_load 

When you are finished working on this exercise, you must submit your work by running give:

give dp1092 lab04_dynamic_load dynamic_load.s

You must run give before Monday 01 January 00:00 (midnight) (Saturday 01 January 00:00) to obtain the marks for this lab exercise. Note that this is an individual exercise, the work you submit with give must be entirely your own.

Submission

When you are finished each exercises make sure you submit your work by running give.

You can run give multiple times. Only your last submission will be marked.

Don't submit any exercises you haven't attempted.

If you are working at home, you may find it more convenient to upload your work via give's web interface.

Remember you have until Saturday 01 January 00:00 to submit your work.

You cannot obtain marks by e-mailing your code to tutors or lecturers.

You check the files you have submitted here.

Automarking will be run by the lecturer several days after the submission deadline, using test cases different to those autotest runs for you. (Hint: do your own testing as well as running autotest.)

After automarking is run by the lecturer you can view your results here. The resulting mark will also be available via give's web interface.

Lab Marks

When all components of a lab are automarked you should be able to view the the marks via give's web interface or by running this command on a CSE machine:

1092 classrun -sturec