#### Quicksort

For this assignment you will write a MAL subprogram for sorting an array of integers using the quicksort algorithm. In order to check the correctness of your code, you will also need a subprogram to display the contents of the array. You can use your `printArray` subprogram from the earlier sort assignment. Finally, you will need a short main program that will be used to test the subprogram. Again, you can use the code from your earlier sort assignment.

#### The `quicksort` subprogram

The `quicksort` subprogram itself is just a nonrecursive shell for the recursive `qksort` subprogram

```void quicksort(int A[], int entryCount) {
qksort(A, 0, entryCount - 1);
}

void qksort(int A[], int ilo, int ihi) {
int pivot;      // pivot value for partitioning array
int ulo, uhi;   // indices at ends of unpartitioned region
int ieq;        // least index of array entry with value equal to pivot
int tempEntry;  // temporary entry used for swapping

if (ilo >= ihi) {
return;
}
// Select a pivot value.
pivot = A[(ilo + ihi)/2];
// Initialize ends of unpartitioned region and least index of entry
// with value equal to pivot.
ieq = ulo = ilo;
uhi = ihi;
// While the unpartitioned region is not empty, try to reduce its size.
while (ulo <= uhi) {
if (A[uhi] > pivot) {
// Here, we can reduce the size of the unpartitioned region and
// try again.
uhi--;
} else {
// Here, A[uhi] <= pivot, so swap entries at indices ulo and
// uhi.
tempEntry = A[ulo];
A[ulo] = A[uhi];
A[uhi] = tempEntry;
// After the swap, A[ulo] <= pivot.
if (A[ulo] < pivot) {
// Swap entries at indices ieq and ulo.
tempEntry = A[ieq];
A[ieq] = A[ulo];
A[ulo] = tempEntry;
// After the swap, A[ieq] < pivot, so we need to change
// ieq.
ieq++;
// We also need to change ulo, but we also need to do
// that when A[ulo] = pivot, so we do it after this if
// statement.
}
// Once again, we can reduce the size of the unpartitioned
// region and try again.
ulo++;
}
}
// Now, all entries from index ilo to ieq - 1 are less than the pivot
// and all entries from index uhi to ihi + 1 are greater than the
// pivot.  So we have two regions of the array that can be sorted
// recursively to put all of the entries in order.
qksort(A, ilo, ieq - 1);
qksort(A, uhi + 1, ihi);
}```

#### Recursion

The qksort subprogram has two recursive calls at the end. Before writing its assembly language code, you should take the time to design the layout of its activation records. In addition to saving and restoring the return address, you will also need to save and restore any temporary or argument registers whose values are assigned before a recursive call and used after a call.

I suggest that you make this assignment easier on yourself: carefully plan and document the use of registers before writing the code.

#### The main program

You can declare an initialized array in the .data section for testing as in the previous sort assignment. The main program should print the array, call the `quicksort` subprogram, then print the array again.

If you write this program in the same folder as the previous program you should just modify the subprogram call in the file containing the main program. Do not create another file with the modified main program. Mars will not be able to assemble/run multiple files from a folder if two of them use the `main` label.

You should try your program with array entries in various orders. Starting with the entries in reverse order gives a good test for the sort algorithm described earlier. Changing the number of entries that you sort can give you some indication of off-by-one errors.

#### What to Turn in

Turn in both a copy of your program and a Mars session record. Use the same test array as in the previous sort assignment.

```testArray:
.word   9
.word   8
.word   7
.word   4
.word   5
.word   6
.word   3
.word   2
.word   1
.word   0```