This assignment has changed from the Fall 2016 version.
In this assignment, you will be implementing binary search on an integer array recursively. Please refer to the following link for an overview of this algorithm: click here. Notice that the array in this assignment is sorted in descending order.
Here is the C implementation:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | #include <stdio.h> // Parameter and result int Needle = 4; int *Result; // Array definition int Count = 7; int Haystack[] = {14, 12, 10, 8, 6, 4, 2}; // Forward declaration int *BinarySearch(int x, int *loAddress, int *hiAddress); // Entry point int main() { Result = BinarySearch(Needle, Haystack, Haystack + (Count - 1)); // Print the result (you don't need to do this in assembly) if (Result) printf("Found at address %p (contains %d)\n", Result, *Result); else printf("Element not found!\n"); } // Binary search recursive function // Adapted from: http://www.cs.utsa.edu/~wagner/CS3343/recursion/binsearch.html int *BinarySearch(int x, int *loAddress, int *hiAddress) { int midOffset = 0; int *midAddress = 0; // Base case (the element was not found) if (loAddress > hiAddress) return 0; // Calculate the address of the element in the middle midOffset = (hiAddress - loAddress) / 2; midAddress = loAddress + midOffset; // Have we found the element? if (x == *midAddress) { // We have found it! return midAddress; } else if (x > *midAddress) { // We haven't found it: continue on the lower half return BinarySearch(x, loAddress, midAddress - 1); } else { // We haven't found it: continue on the upper half return BinarySearch(x, midAddress + 1, hiAddress); } } |
Note that the array that we perform the search on is called the
Haystack
, and the element we are searching for is called the
Needle
. The BinarySearch
function is supposed to
return the memory address where the element is located (or 0 if it is not in
the array). Also, notice that the Count
variable must contain the
number of elements in the Haystack
array.
c11 -o bsearch bsearch.c
./bsearch
BinarySearch
function only. The
Main
function is given to you. Do not change it. Notice that
the return value of your function is not printed (like in the C
implementation). It is stored in the Result
label. Your program
must eventually get to the HALT
instruction in the
Main
subroutine. At that point, your return value should be
in the Result
label and R5
and R6
should be restored to x4000
.BinarySearch
label.Haystack
array is already sorted in
descending order. Also, assume that it will not be larger than 20
elements. Do not assume that the elements in the array are unique.Main
function in the skeleton file
so that you find out what is being given to you and how your return value is
being used.
You must follow the following stack protocol in this assignment:
R5
and R6
are initially set to
x4000
(the Main subroutine does this for you).JSR
.R7
in a label,
except that we are storing it in the stack instead of a label.R5
(by LC-3 conventions). Hence, in this
step, we push the value of R5
into the stack.R5
. The convention is to make the frame pointer point
to where the first local variable is (or would be).midOffset
variable must have a higher address than the midAddress
variable (midOffset
is pushed before midAddress
).
Do not modify R5
, R6
, and R7
in your
function outside of what the stack protocol demands.
To help you overcome any addiction you may have to preliminary testing, we have decided to provide only one preliminary testing case: to check if your program assembles.
That said, we also decided to provide you with screenshots of what the stack should look like for some test cases (you can be sure we will not test those specific cases).
Note: the stack you get should match, except possibly for the return address of the activation records above the first one. The return address for the first activation record must match. If it does not, you did something wrong.
Test Case 1:
This is what the needle and the haystack look like:
When my program reaches the HALT
instruction in the
Main
subroutine, my Result
label and stack look like
this:
And R5 = x4000
, R6 = x4000
,
R7 = x3011
.
Test Case 2:
This is what the needle and the haystack look like:
When my program reaches the HALT
instruction in the
Main
subroutine, my Result
label and stack look like
this:
And R5 = x4000
, R6 = x4000
,
R7 = x3011
.
Preliminary Testing (1 point):
We will check that your program assembles.
Final Testing (99 points):
To test your program, we will take advantage of the fact that when something
is popped off the stack, the value remains in memory. Hence, we will run
your program up to the HALT
instruction. Then, we will dump the
stack and the values of the R5
, R6
, and
R7
registers. We will check that your stack matches our solution
(except possibly for the return address - the only return address that must
match is the one in the first activation record). We will test your program
with different values for the Needle
, the Count
, and
the contents of the Haystack
array.
There is very little room for partial credit (if any). We will not change the auto-grader to accommodate your own stack protocol or your own implementation. For example, if the order of the parameters in your stack is different from ours, you might not get any points (even if you got the right answer).
The grading criteria are deliberately vague: you will have to design your own test cases. We reserve the right to test corner cases.
If you feel that there are ambiguities in the instructions that the provided test screenshots do not resolve, let us know early.