The goal of this assignment is to implement and use leaf functions, recursive functions, string to decimal conversions, decimal to string conversions, variable length argument lists, and C linkage in SPARC assembly code.
In this assignment, you will write a modified version of the printf() function in SPARC assembly code which can be called from a C program.
The ANSI C prototype for the myprintf() function is as follows:
void myprintf(const char *format, ...);
The first argument is a required format string. It is followed by zero or more optional arguments. The number of arguments needed is determined by the contents of the format string. The output of the function is sent to the standard output (file descriptor 1) using the write service request and the trap instruction.
The format contains two kinds of items: plain characters and conversion specifications. Plain characters are simply copied to the standard output. Conversion specifications begin with a % and end with a conversion operation character from the set: u, s, and %.
%u interprets the next argument in the parameter list as a 32-bit unsigned integer and prints its decimal representation.%s interprets the next argument in the parameter list as the address (a pointer) of a null-terminated character string (type const char *) which is printed. If the address is 0 (i.e., NULL), the behavior is as if a pointer to the string "NULL" were supplied.
%% causes a single percent sign to be printed. This does not consume an argument from the argument list.
Anything not listed above is not a conversion specification and is printed verbatim. See the example below.
The format argument is the address of the format string, and the format string is terminated by a null character (ascii code 0).
If a NULL pointer is passed as the first parameter, myprintf() should behave as if a pointer to the string "NULL\n" were given as the format string.
Given the program:
extern void myprintf(char *, ...);
int main(void)
{
myprintf("Simple Test\n");
myprintf("Simple Test with ignored arguments\n", 1, 2, 3);
myprintf(NULL);
myprintf("%s\n", "Hello, World");
myprintf("%s\n", NULL);
myprintf("0=%u 4294967295=%u\n", 0, 4294967295UL);
myprintf("%u%% is perfect\n", 100);
myprintf("%100xs\n", "Not Used");
myprintf("%1u %1r %1%\n");
myprintf("%s", "Go" "od");
myprintf("%s\n", "bye");
return 0;
}
The output is:
Simple Test Simple Test with ignored arguments NULL Hello, World NULL 0=0 4294967295=4294967295 100% is perfect %100xs %1u %1r %1% Goodbye
My solution used eight helper functions in addition to the myprintf() function. I suggest you first implement and test this program using C. Write drivers which will test the helper functions. Now, one at a time, create an equivalent SPARC routine for each C function. Start with a simple leaf function (such as the one which print one char to stdout). Link it with your working program so that everything is in C except for this low-level function. Test it carefully. Continue by translating and testing each function until at last myprintf() is complete.
Submit your file electronically with the command:
/u/cs217/bin/submit 6 myprintf.s
Due: submitted by 11:59pm, Thursday, November 30, 2000.