Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!utgpu!water!watmath!clyde!rutgers!husc6!cmcl2!brl-adm!adm!RMRichardson.PA@Xerox.COM From: RMRichardson.PA@Xerox.COM Newsgroups: comp.lang.c Subject: Re: another auto-increment problem Message-ID: <9600@brl-adm.ARPA> Date: Sat, 3-Oct-87 01:05:23 EDT Article-I.D.: brl-adm.9600 Posted: Sat Oct 3 01:05:23 1987 Date-Received: Sun, 4-Oct-87 00:37:54 EDT Sender: news@brl-adm.ARPA Lines: 54 From: Henry Spencer > The reason for right-to-left is in two parts. First, functions > like printf are a lot easier to implement if arguments, once > pushed, are in ascending order in memory, e.g. argument 3 follows > argument 2. Second, many modern machines have stacks that grow > downward in memory, i.e. the latest thing pushed is below the > previous thing pushed; the PDP11 did it that way for complex > reasons, and many others have copied the 11. Putting these two > considerations together, if the leftmost argument is to be at the > lowest location in memory, it must be pushed last. Hence > right-to-left. Hmmmm, ... If one were using a stack as a stack, and not as a "sort of managed" array, then I think Henry has the "right" conlusions for the "wrong" reasons; which way the items are addressed on the stack or whether the stack runs "up" or "down" in memory wouldn't matter. For a true stack, the items on the stack should be in order of use, first item on top, or to reverse the description of a stack, first used, last pushed. Thus for printf, the first thing one wants is the formatting description. printf will pick this up and start forming the output stream of characters until it hits the first conversion specification, e.g., %d, at which point it needs the first value, i.e., the second argument, popped off the stack. This continues until it runs off the end of the formatting string or runs out of arguments. Thus for an architecture using a call stack, it pays to push the last (right most) argument first (First In Last Out). In a "high level" language, the direction of the stack in real memory is invisible and irrelevant. Of course, there is a "work around" if the arguments are pushed on the stack first argument first; the function can implement its own stack and pop each item off the call stack and push it onto its local stack, then run off its local stack. Ugly, but possible. Next question: How many machines / compilers really use a stack this way for passing and processing arguments? (As opposed to pushing the arguments and "dragging" them out of something that looks more like an array.) If the implementation is using the "stack" more like an array, then Henry's explanation really may make more sense; one wants the order of the arguments set up to ease the access to them, and one cares about the order in memory. Note that "older" architectures (e.g., CDC 3000 or 6000 series) were more likely to stuff the arguments into a temporary array (sometimes right after the call instruction) and pass a pointer to it (sometimes the return link itself). Thus, the argument processing was usually left to right on these machines. (Then again, the "high level" language was FORTRAN and recursive calls were not supported.) Rich