1.] Write a C program that defines the following struct:
struct IntArray { int length; int *dataPtr;
};
and the following functions:
• struct IntArray* mallocIntArray(int length): allocates, initializes, and returns a pointer to a new struct IntArray. Hint: see example from class – also, you’ll need two malloc calls, one for the instance and one for the instance’s dataPtr (a pointer to an int array of size length).
• void freeIntArray(struct IntArray *arrayPtr): frees the instance’s dataPtr and frees the instance.
• void readIntArray(struct IntArray *array): prompts and reads ints from the user to fill the array (i.e., read one int for each array index). Your program should print an error message and prompt again if the user enters a value that cannot be parsed as an int. Hint: I recommend using fgets and strtol – you can Google for examples of these (cite your sources) and we’ll cover them in labs.
• void swap(int *xp, int *yp): swaps the int values stored at the xp and yp pointers.
• void sortIntArray(struct IntArray *array): sorts the input array in ascending order using Selection Sort (Google it, cite your sources) by repeatedly calling your swap function as appropriate.
• void printIntArray(struct IntArray *array): prints the array (e.g., “[ 1, 3, 5, 7 ]”).
• int main(): prompt the user to input a positive int length from the user (print an error message and prompt again if the input cannot be parsed as a positive int), call mallocIntArray to create an array, call readIntArray to prompt the user to fill the array, call sortIntArray to sort it, call printArray to print the resulting sorted array, then call freeIntArray to free the heap memory used by the array.
Name your source file 3-1.c.
Here is output from a sample run of the application (your output does not need to match exactly):
Enter length: cat
Invalid input
Enter length: 5
Enter int: 3
Enter int: puppy
Invalid input
Enter int: 7
Enter int: 5
Enter int: 8
Enter int: 2
[ 2, 3, 5, 7, 8 ]
2. Consider the following C function: long f(long a, long b, long c);
When compiled, the resulting x86-64 code for the function body is:
Assume that a is in %rdi, b is in %rsi, c in %rdx.
Your task is to reverse engineer the C code; specifically, to write a C implementation for the decode function that is functionally equivalent to the compiled x86-64 code above.
Also write a main() function to test your function.
Hint: try compiling your C code to x86-64 on Arch using gcc -Og -S 3-2.c as you work. Note that the output assembly does not need to match the x86-64 code above exactly – it just needs to be functionally equivalent.