The PDP-11 was especially designed to allow code to be written in either of the three common addressing schemes:
- Zero Address (Stack)
- On Address (Acumulator)
- Two Address
There's a quite nice paper Gordon Bell (et. al) wrote describing the PDP-11 architecture (*1), which in great detail talks about the ability to handle a stack machine using either register - except R6 and R7 that is, as they are predefined as Hardware Stack and PC. It is the combination of features (*2) for their new mini-computer (*3), that may confuse a bit.
[...]the stack grows downward. [...] But isn't that just convention? From what I understand we could equally well reverse the direction[...]. Yet every document I see says the stack grows downward on the PDP-11. So what am I missing?
It's the hardware stack. While each register (*4) can be used to manage a stack structure, R6 is tied to certain instructions and hardware functions manipulating this stack. To keep it manageable two assumptions are common to all of them:
- The (R6) stack is word sized
- The (R6) stack grows downward
For example JSR pushes the return address down on R6, while RTS pulls it upward. Similar all hardware interrupts/trap will use the same fashion. So, unless one can take the risk of having the top of stack destroyed by any of those, going along and using R6 is a downward fashion is a must.
Of course, this does not hinder any programming (language) to let the hardware stack run for itself and use any other Register (R0..R5) for their own purpose - like one (or more) software stacks managing procedure passing and local data structures. Forth may be the best known example here.
The mentioned paper goes into great detail that the PDP-11 is well suited to handle stack orientated programming so due its auto-indexing instruction set.
Still, while the handling of a data stack can easy be implemented using any other register, the return stack is hard to be moved, as there are no simple instructions replacing JSR/RTS. Sure, one could use some /360-like mechanics, but missing a LINK type instruction each call would be something like
MOV [Rmystack]+,PC
JMP subroutine
while returning would translate to
MOV R0,-[Rmystack]
ADD R0,2
MOV PC,R0
Doesn't look great with just the little memory they had back then, not to mention execution time.
Bottom line: The Hardware Stack (R6) is quite useful due it's implied use of R6 but ties it's working to being downward and word sized.
So, why do we then not use a different software stack for parameter passing, growing upward or being of different (byte) size? Well, as so often 'Hail C' is the answer. When C was developed, they decided to accept the limitations and go with the hardware stack. It removes the need to use a separate register and, at least for simple issues, it's as good as any other. As a result we got stuck with a downward growing word sized stack and the evil mix-up of program flow management and data management.
*1 - Made for a speech during the Minicomputers - the profile of tomorrow's components track at the AFIPS Spring Joint Computer Conference in May 1970 in Atlantic City and published in Volume 36 of their proceedings.
*2 - They tried to dance on as many weddings as possible. Process control as well as scientific computing and general purpose. Hardware supported CISC structure as well as simple and symmetric instruction set for high level (synthetic) programming.
*3 - The paper starts with a real nice definition of what a micro-, mini- and midi-computer is by defining them by number of registers, word length, memory size, memory speed and cost. A worthwhile metric to be copied here to not only show that these terms weren't (and aren't) as settled as one assumes today, as well, as it's about capabilities, not size.
Address Word CPU Cost Data
Space Size State Types
(Words) (Bits) (Register) (1970 USD)
Micro 8k 8~12 2 5k Integer, bit Vector
Mini 32k 12~16 2-4 5~10k Indexing
Midi 65~128k 16~24 4-16 10~20k Floating Point
It also shows that even the most basic of today's microcontrollers (AVR, PIC, not to mention ARM) may well be placed in the Midi category of 1970, if not Mainframe :)
*4 - Using R7 can as well be a bit ... well, lets say complicated :))