COS 217. Introduction to Programming Systems. Spring 1999.

Implementing myprintf()

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 %, have an optional unsigned decimal integer, and end with a conversion operation character from the set: u, s, r, and %.

%u interprets the next argument in the parameter list as a 32-bit unsigned integer and prints its decimal representation. In this conversion specification there can be no optional integer between the % and the u.

%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. There can be an optional unsigned decimal integer between the % and the s which is used as the maximum field width. For example, if the value is 20, then no more than 20 characters of the string will be printed (less if the string is less than 20 characters). If the optional integer is missing, it is as if the maximum possible value of 4294967295 (232-1) were specified. If the optional integer is larger than this maximum, it is as if the maximum were specified. (Implementation note: Build this integer digit by digit until either: (1) all the digits have been processed or (2) you have determined that the number is larger than the maximum value. In the later case you do not need to actually determine what the number is.)

%r causes a random number generated by a call to the C standard library function rand() to be printed using the %u conversion specification. This does not consume an argument from the argument list. There can be no optional integer between the % and the r.

%% causes a single percent sign to be printed. This does not consume an argument from the argument list. There can be no optional integer between the % characters.

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("%10s\n", "Hello, World");
   myprintf("%00000000000000002s\n", NULL);
   myprintf("%4294967297s\n", "Hello, Again");
   myprintf("%s%r%s%r%s%r\n", "rand()=", " rand()=", " rand()=");
   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
Hello, Wor
Hello, Again
rand()=16838 rand()=5758 rand()=10113
0=0  4294967295=4294967295
100% is perfect
%1u %1r %1%

Ground Rules

These rules are designed to constrain the number of possible solutions. This will make the assignment easier to grade and help meet the goals stated at the beginning of the assignment.


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 multiplies by 10). 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.


The grading guidelines are as follows:


Submit your file electronically with the command:

/u/cs217/bin/submit 6 myprintf.s

Due: submitted by 11:59pm, Monday, April 12, 1999.

Copyright © 1998 by Scott C. Karlin