Interesting. They were explicitly addressing the stack to iterate through arguments, yet the prototype lists nine arguments in addition to the fmt string. Is that function actually variadic? If so, why explicitly list x1 through x9 as arguments?
I think what's going on here is that the local variables in a function are directly adjacent in memory to the arguments, so if it wasn't declared to have that many arguments, the local variables would start at the same location in memory as the first undeclared argument and the undeclared arguments would get clobbered.
As it is now, you push all your function arguments to the stack before you push your locals. If you call printf(a1, a2, ... , an), it pushes n arguments, then the instruction pointer, then your locals. No clobbering necessary.
Maybe 1972-era C pushed arguments to the stack according to the signature defined in the function definition rather than the function call? (i.e. printf would have 10 pushes no matter how many arguments you actually passed to it). If it pushed according to the function signature, you'd waste memory and have a hard limit to how many arguments you could pass. And you'd waste push instructions. So I don't know why it's written the way it is, but corrupting your locals doesn't seem like a likely explanation. Maybe they're trying to mollify the compiler?
I think the x2,...x9 were declared just as "documentation". Really early C didn't have any types that would get passed as anything but a single word on the stack, IIRC.
(as I was going to add before getting noprocrast-blocked)
Ha, so it doesn't matter how the function is defined! You can call any function with any arguments you want, just shove 'em on the stack and see what happens. And people say ANSI C is too unsafe ;)
I've used a C compiler[1] that implements old K&R semantics without "...". In fact, I used it to write a printf just last week[2]. All you need to do is make a pointer to one of the arguments and increment the pointer to take in variable arguments--which is exactly what this code does. The difference is, the compiler I used didn't require any parameters except fmt to be explicitly declared.
(Why do I have experience with strange, non-compliant 16 bit C compilers? Because I have an eccentric professor for my operating systems class, apparently.)
Seems like they're trying to accommodate the default "fallthrough" behavior of the switch without using break, either because break hadn't been invented or because they explicitly wanted to bypass the code below the switch block.
EDIT: On further inspection, the code below the switch block is meant to behave like a "default" block. I bet this is before they invented "default".
"The software retains the copyright of the original authors and is currently licensed under the Caldera ancient UNIX license." - as mentioned in the homepage, yet the code license information on the right side says GNU General Public License v2. Is this because google only allows a limited number of licenses on code.google.com ?
Interesting to see the implementation of something like printf though: http://code.google.com/p/unix-jun72/source/browse/trunk/src/...