CS/COE 447 Programming Assignment 3 ================================== All programs should be submitted via e-mail to your grader (mhanna@cs.pitt.edu). Make a single zip file of both the files you are submitting. The subject line of your message should be 447: Programming Assignment 3 -- your name. In this assignment, you will become familiar with the implementation of multi-dimensional arrays and linked lists. ================================== Part 1 As they are implemented, 2-dimensional arrays are stored in either ``row-major'' order or ``column-major'' order. In row major order, the elements of the first row are stored consecutively, then the elements of the second row, and so forth. In column major order, the elements of the first column are stored consecutively, then the elements of the second column, and so forth. For example, consider a two dimensional array with 3 rows and 4 columns: A[0,0] A[0,1] A[0,2] A[0,3] A[1,0] A[1,1] A[1,2] A[1,3] A[2,0] A[2,1] A[2,2] A[2,3] Using row-major order, the elements are stored in memory as follows: A[0,0] A[0,1] A[0,2] A[0,3] A[1,0] A[1,1] A[1,2] A[1,3] A[2,0] A[2,1] A[2,2] A[2,3] Array Data Structure: The array is a 2-dimensional array, stored in row-major order, of 1-word signed integers. It should be stored as part of a data structure where the first word is the number of rows in the array and the second is the number of columns, followed by the elements of the array itself. You can create the array in memory using .word (no need to input the values). Procedure SumRow: Write the following subroutine (which should follow the calling conventions for registers as listed on the green card). Also, write a main program that calls it, so you can test it. Hint: there is some code in Chapter 3 that you may find very helpful (pp. 210-212). ## # Procedure SumRow(array, RowNum) # # ``array'' (passed in $a0) is a pointer to an array data structure as # described above.# # # ``RowNum'' (passed in $a1) is an integer between 0 and the number of # rows in the array minus 1. # # Purpose: Calculates the sum of the elements in row ``RowNum'' and # returns it in $v0. # # No error checking is required. Choose array elements such that # the sum does not overflow a single register. # # ================================== Part 2 The following is a singly-linked list stored in memory. ``list'' points to the front of it. A next pointer of 0 indicates the end of the list. The elements are sorted in increasing order. If list contained 0, that would mean that the list is empty. .data .word 0x2,0x10010018,0x6,0x10010020,0xa,0x10010028,0x4,0x10010008,0x8,0x10010010,0xc,0x0 list: .word 0x10010000 newline: .asciiz "\n" blank: .asciiz " " .align 2 alloc: Each node of the list contains the data stored in that node and a pointer to the next node in the list. A pointer to the front of the list needs to be maintained. Above, list contains the address 0x10010000. Thus, the first node in the list is stored at 0x10010000. The data of that node is 0x2, and the next pointer of that node is 0x10010018. Thus, the second node of the list is stored at 0x10010018. The last node of the list is the one whose data is 0xc, since its next pointer is 0. If you assemble the above code in Mars, you will be able to see which nodes are stored where (and draw the list on paper). Because each node contains a pointer to the next one, the nodes of a list do NOT need to be stored sequentially in memory (as array elements need to be). In this assignment, we will only insert values into the list (not delete them as well). We'll use the memory locations starting at address "alloc" for the new elements. To insert a value into a sorted list, first create a new node, with that value as its data. Then, starting at the beginning, traverse the list until you find where the new node should go (so that the list will still be sorted after). Finally, splice the new node into the list, so that the node before it points to *it*, and *it* points to the node following it. For example, to insert a 5 into the following list: list --> 1 --> 3 --> 7 --> 9 You need to do this: list --> 1 --> 3 --> 5 --> 7 --> 9 That is, you need to make 3 point to the new node, and the new node point to 7. Two special cases need to be handled: inserting a node into an empty list, and inserting a node that belongs at the end of the list (e.g., inserting 11 into the example above). This question is to write the following subroutines. As above, the subroutines should follow the calling conventions for registers as listed on the green card. Also, write a main program that calls your subroutines, so you can test them. Call insert 3 times: once with -1, once with 7, and once with 0xe. Please call PrintList before calling insert, and then after each call to insert. (You don't need more sophisticated printing than including newlines and blanks.) The main program should dedicate one register, $s0, to use for memory allocation. $s0 should not be used for anything else by either of the subroutines. It should be initialized to ``alloc''. When you call insert, the new list element should be stored at locations $s0 and $s0 + 4. Then, $s0 should be updated so it points to the next free memory location (where the next inserted list item should be stored). ## # Procedure PrintList (list) # # list (passed in $a0) is a pointer to the first node of a # singly-linked list of 1-word integers. # # Purpose: Print the elements of the linked list in order # # No error checking is required (though your code should work if the # list is empty, which is indicated by list containing 0) # ## #Function Insert (list,value) # # list (passed in $a0) is a pointer to the first node of a # singly-linked list of 1-word integers whose elements are sorted in increasing order. # # elem (passed in $a1) is an integer to be inserted into the list. # # Purpose: insert elem into its proper place in the linked list so # that the list remains sorted. # # Return (in $v0) the new value of list (since it will change if the new # node becomes the first node of the list) # # No error checking is required (though your code should work if the # list is empty, which is indicated by list containing 0) # # Algorithm: (Make sure you understand this algorithm before working on implementing it in MIPS) p-->data refers to the data field of the node pointed to by p p-->next refers to the next field of the node pointed to by p returnValue = list newPtr = pointer to a new node newPtr-->data = elem previousPtr = 0 currentPtr = list while (currentPtr != 0 && elem > currentPtr-->data) { previousPtr = currentPtr; currentPtr = currentPtr-->next; } if (previousPtr == 0) { newPtr-->next = list returnValue = newPtr; (The caller should update list to this value) } else { previousPtr-->next = newPtr; newPtr-->next = currentPtr; } return returnValue