The first computer I owned was an Apple II Plus. It had a 6502 chip with an accumulator register and a couple of index registers. From a programmer’s point of view, most of the work got done in the accumulator and half the machine cycles were spent doing loads and stores (load a value, add, store, …). Essentially, it was a one register machine. So when I started programming IBM mainframes, I was delighted to see that each machine came equipped with 16 general purpose registers. Why so many? Who needed so many registers?
As is often the case, I was wrong:
Register 0 – used occasionally to pass a parm
Register 1 – used for parameter passing
Register 2 – Available, but sometimes corrupted by TRT
Register 12 (And perhaps a few others) – Your typical base register
Register 13 – Points at a save area
Register 14 – Points to the return address
Register 15 – The target address for program calls and the return code register
So … what does that leave us? Registers 2 through 11, or 3 through ?
Dive into many production programs and you’ll find that all the registers were allocated years ago. Good luck finding a free register. Many programs are so code-bloated that simply adding another variable will cause thousands of addressability errors. What’s a programmer to do?
There are two strategies:
1) Store the values in one or more registers. Do the work you need to do. Restore the registers to their previous values. Ugly, but effective.
2) Start a new program, pass it the data it needs, return the values you have computed. The nice thing about this approach is that you start from a clean slate. All the registers are yours to use as you see fit.
So … do we have enough registers or not? It would be nice to have more, but I think 16 general purpose registers are sufficient. Sometimes, constraints are a good thing – think Haiku. In writing assembler programs, we need to think smaller and more modular. Many maintenance assembler programmers use strategy 1 because it’s easier and they can turn the work out faster. But in many cases, particularly for programs that have maxed out the storage covered by existing base registers, the second strategy may be the best choice.
If you are writing something new, one base register should be sufficient. If you find you need a second base register, it’s probably time to re-factor. Small is beautiful