Reference no: EM132326249
In this assignment, you will be creating and testing a subroutine that can perform arbitrary-sized addition. This subroutine will take arguments using the ARM Application Procedure Call Standard (APCS), and probably make use of the stack for other purposes.
Exercise - asuAdd Subroutine
In the "studentWork" project for Eclipse, fill in the asuAdd subroutine in the file asuAdd.S. The purpose of asuAdd is to do arbitrary-sized unsigned additions. One use of asuAdd can be to create a Fibonacci subroutine that can accurately calculate the Nth Fibonacci number for large values of N. So N=1000 should be no problem for example. When being called, asuAdd takes three arguments in r0, r1, and r2. r2 contains an argument called maxN0Size as described below. r0 and r1 point to arrays of 32-bit unsigned ints. Element 0 of each array stores the number of words that contain valid data in the array. For example, if element 0 contains the value 23, then the following 23 words contain valid data. The least-significant word comes first, so this is a little-endian style. Note that, now, the ARM simulator that I have built uses a little-endian version of the ARM7 processor (see https://en.wikipedia.org/wiki/Endianness). The arbitrary-sized unsigned data pointed to by r1 is added to the arbitrary-sized unsigned data pointed to by r0 and the result ends up in the arbitrary-sized unsigned data pointed to by r0. If element 0 of an array contains 0, then the value of the arbitrary-sized number as a whole is, by our definition, 0.
Sometimes a carry out in the final "partial" addition will cause a developing sum needing, up to this point, N valid words to increase in size such that it requires (N+1) words to be fully stored.
For example (written for convenience in "big-endian" style - the words are actually reversed in memory in the little-endian style):
0x80000000,80000000,80000000 +
0x80000000,80000000,80000000
0x00000001,00000001,00000001,00000000 +
This is all good and well, but what if there is no available space in memory for the extra word in the expanded result integer where that result integer is located?
I am proposing a subroutine that conforms to the following c-language function signature (using the provided typedef):
typedef unsigned int bigNumN[];
// returns -1 for error in inputs, 1 if overflow/carry-out and 0 if no overflow/carry-out
int asuAdd(bigNumN bigN0PC, const bigNumN bigN1PC, unsigned int maxN0Size);
where maxN0Size specifies the maximum number of valid words that can fit in the bigN0PC array (that is, the array size less one because word 0 in the array stores the number of valid words). In register r0 in normal cases, the subroutine returns 1/0/-1 as indicated in a comment above the function signature. maxN0Size should always be greater than or equal to the maximum of the valid words in bigN0PC or bigN1PC. If it is not, you should return -1 indicating an error condition.
Here are some examples:
Consider bigN0PC has 1 valid word and bigN1PC has 2 valid words. If maxN0Size is 1 then that is an error so in register r0 return -1 from the subroutine. If maxN0Size is 2 then there is no error, and the return value may be 0 or 1 depending. If maxN0Size is 3 in this case then the return value of the function (in register r0) will always be 0 because 3 words is always large enough to hold whatever sum is possible from an addition with operands of less than 3 words (like the 1- and 2-word operands specified in these examples).
The template project for this assignment contains testing code to test your asuAdd subroutine. It calls a library function called memcmp to compare values in memory. The linker links memcmp to our code. This is the same memcmp that can be used from C-language. Parameters to memcmp are passed in order in r0 through r2, and the return value is returned in r0.
Please add many more rows of data to the testing table so that you are doing thorough testing of your subroutine. You may also modify things to add more elements to arrays. Note, element 0 of each input array for a given test needn't contain the same value.
There might be a prize for the pair of students who come up with the fastest implementation for the bigAdd subroutine. Details to be provided if we go ahead with this. If there is a tie, the subroutine taking less space will break the tie. As mentioned in class, we expect that every student will work with a partner on this assignment.
To demonstrate that the testing code works, I have also provided a project with a C++ implementation of asuAdd. In your implementation, make use of the carry flag in the status register when doing additions. In C and C++ as defined by the language standards, there is no way to access the processor's carry flag. Therefore, I simulate a carry flag. The carry flag is simulated in a C++ class template that normally provides a C++ object wrapper for each numeric C++ primitive type. I have simply hacked the template so that we can simulate a carry flag for unsigned types, like unsigned int. In order to make things look simpler when calling asuAdd from assembly code, I have given the asuAdd function a C- language interface.
It is suggested to ask on Piazza if you have any questions.
Attachment:- Assignment.rar