Quicksort Assembly Subroutine Assignment for CS 322, Assignments of Computer Science

An assignment for cs 322 students to write an assembly language subroutine named qs, which sorts an array of double precision numbers into ascending order using quicksort. The students are required to write the assembly code, pseudo-code or c code, and comment every line indicating what it does in terms of the pseudo-code. The document also includes some hints and instructions for the sparc v8 architecture and register conventions.

Typology: Assignments

Pre 2010

Uploaded on 08/19/2009

koofers-user-85e
koofers-user-85e 🇺🇸

5

(1)

10 documents

1 / 3

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
CS 322 Homework 2 due 1:30 p.m., Wednesday, Feb. 2, 2005
The goal of this assignment is to re-acquaint you with assembly language programming in general
and with the SPARC V8 architecture in particular. It is not directly connected with your PCAT
compiler project, but should prove useful background for your code generator.
Write an assembly language subroutine qs, suitable for calling from C, that sorts an array of
double precision numbers into ascending order using quicksort. The calling interface is given by
void qs(int n, double *a)
where ais the array to be sorted, and nis its size. The array should be sorted in place. Of course,
you may choose to implement qs using additional, private subroutines if you wish.
For example, if your routine is linked with the following main program:
double a[] = {1.1,5.5,3.3,2.2,4.4};
main () {
int i;
qs(5,a);
for (i = 0; i < 5; i ++)
printf ("%f ", a[i]);
printf("\n");
}
it should produce the following output:
1.1 2.2 3.3 4.4 5.5
Of course, your code should also work when linked against more interesting main programs (like
the private one we’ll use as a test driver)!
In addition to the assembly code itself, you must turn in pseudo-code or C code corresponding to
your assembly code, and you must comment every line of the assembly code indicating what it
does in terms of the pseudo-code. For example, if the pseudo-code contained a line
x = t
the assembly code might contain the following commented lines:
ld [%fp-36],%i4 ! fetch t
st %i4,[%fp-40] ! store into x
It is also useful to include a comment explaining where each pseudo-code variable is held (i.e.,
which register or stack frame slot).
1
pf3

Partial preview of the text

Download Quicksort Assembly Subroutine Assignment for CS 322 and more Assignments Computer Science in PDF only on Docsity!

CS 322 Homework 2 – due 1:30 p.m., Wednesday, Feb. 2, 2005

The goal of this assignment is to re-acquaint you with assembly language programming in general and with the SPARC V8 architecture in particular. It is not directly connected with your PCAT compiler project, but should prove useful background for your code generator.

Write an assembly language subroutine qs, suitable for calling from C, that sorts an array of double precision numbers into ascending order using quicksort. The calling interface is given by

void qs(int n, double *a)

where a is the array to be sorted, and n is its size. The array should be sorted in place. Of course, you may choose to implement qs using additional, private subroutines if you wish.

For example, if your routine is linked with the following main program:

double a[] = {1.1,5.5,3.3,2.2,4.4};

main () { int i; qs(5,a); for (i = 0; i < 5; i ++) printf ("%f ", a[i]); printf("\n"); }

it should produce the following output:

Of course, your code should also work when linked against more interesting main programs (like the private one we’ll use as a test driver)!

In addition to the assembly code itself, you must turn in pseudo-code or C code corresponding to your assembly code, and you must comment every line of the assembly code indicating what it does in terms of the pseudo-code. For example, if the pseudo-code contained a line

x = t

the assembly code might contain the following commented lines:

ld [%fp-36],%i4! fetch t st %i4,[%fp-40]! store into x

It is also useful to include a comment explaining where each pseudo-code variable is held (i.e., which register or stack frame slot).

Your code must be in a separate file qs.s; don’t use gcc’s special mechanisms for including in-line assembly code. Your explanatory C code or psuedo-code should be included as a block comment in this file.

Strive for correctness, clarity, concision, and efficiency, in that order. For full credit, you must address all these criteria!

Quicksort

There are many published descriptions of quicksort; I suggest the one given in Cormen, et al., Introduction to Algorithms , MIT Press (Ch. 8.1 of 1990 edition or Ch. 7.1 of 2001 edition), or the one in (any edition of) Sedgewick, Algorithms , Addison-Wesley. Don’t bother to compute the partition element location in some fancy way like “median of three;” just use the first or last element of the (sub)array.

Hints

Giving the -S option to cc or gcc together with a .c file produces a file with .s extension containing the assembly code generated by the compiler for that .c file. This can be very useful for seeing what instructions the compiler chooses, exactly what the function calling conventions are, etc. You may want to write qs in C first (a pointer-based version will compile to better code), and use the generated code as the basis for your own routine. This approach won’t help you with the explanatory comments, though! And you will probably need to improve this code further by hand to avoid being penalized for obvious stupidities in the compiler-generated assembler. Incidentally, also specifying -O2 to gcc is a good idea, because the resulting code will be both more efficient and clearer.

Integer register conventions on SPARC are described in Appendix D of the SPARC Architecture Manual. Note that any non-leaf subroutine (i.e., any subroutine that may call another subroutine) must begin by creating a stack frame of at least 96 bytes, using an instruction of the form save %sp,-96,%sp, and must conclude with a restore instruction; otherwise, don’t mess with %sp. After the save instruction has been executed, you’ll find the input arguments in %i0 and %i1, the frame pointer in %fp (which is the same as %i6) and the call address in %i7 (the return address is 8 more than the call address). You can use the other integer registers freely, bearing in mind that the %o registers aren’t saved if you call another procedure.

You can assume that the caller saves any floating point registers (which are not windowed), so you can use them freely. Note that double-precision floats (64 bits) are stored in adjacent pairs of %f registers, where the first of the pair must be an even number (e.g. %f0 and %f1 or %f6 and %f7). An instruction like ldd [a],%f2 actually loads %f2 and %f3 with a 64-bit quantity from memory address a. Note also that there is no way to move floating point numbers directly to or from the integer registers; you have to go through memory(!). Don’t forget that memory locations referenced in double-word load or store instructions must be aligned on 8-byte boundaries. Also, there is no fmovd instruction; to move a double from one pair of registers to another, you must do two fmovs instructions. (The assembler in /usr/ccs/bin/as accepts fmovd as a synthetic