Why I often refuse to use symbolic references to hardware features

I often hear recommendations couched in emotional terms about the absolute necessity of making references to hardware features symbolic. One person, in self parody, pretended to suggest that languages such as C should not allow numeric constants. This is a somewhat emotional response. I will try to be rational but perhaps there are emotional issues here, on both sides, that I have not yet understood.

First I mention some history. I first programmed the IBM 650. The manual had a short section on each command providing a numerical op-code, and prose description of the function. No mnemonic was suggested and indeed no assembler came with the machine; it was first delivered about 1954. A very short loader would read in code from punched cards with no processing. Clearly the only way to get a program going was to use a key-punch to prepare the program. One used the decimal order codes to instruct the machine. I remember several of the codes to this day. After I ceased using the machine assemblers were introduced such as SOAP.

The next machine that I programmed extensively was the IBM 704 which came with a rather elaborate assembler (NYAP). The machine manual and its index were oriented to identifying each instruction with a three letter mnemonic. The assembler used those mnemonics. The format of the card input required these three letters to be in columns 8 thru 10. No one attempted to program that machine with numeric op-codes. There were several differences between the machines that made symbolic references more appropriate for the 704 but high on this list is the fact that the official definition of the instructions was accompanied by recommended mnemonics. All of the literature and software recognized just those mnemonics. A new assembler, SAP, was provided by Roy Nutt from Computer Sciences Corporation. It came with source, on cards, and a binary deck. Its input was in a new free-form format, at least after column 8. It soon became the standard assembler, even within IBM. Here is a story about that.

Writing C programs that access hardware features raises the issue of how the many necessary numeric codes are to appear in the program. There is a venerable tradition to put definitions in header files. This greatly irritates me. I find myself (hopefully) with the hardware manual and the C source. The two use two different names. The beginning of the C source names some header files. The source for those is often inaccessible and I must guess which hardware codes match which symbolic definitions. Really cool header files refer to other header files. The facts about which header files are seen by the compiler may be buried deep in the logic of make files. If I am trying to find out why some program fails I feel that I must be suspicious of those symbolic references for my experience is that that is often where the bug lies. Instead of merely studying the C code and the hardware manual I find myself greatly distracted by the mechanics of header files, make files, and another set of naming conventions. It is as if I had to speak several extra languages, none of which bear on the question at hand. If one programs a machine in assembler he must learn most of the instructions and there is little advantage in learning the numeric codes for those instructions. Most of the fields of obscure privileged registers are seldom consulted by even the professional systems programmer, however. Usually preparing or studying code involving such fields is done only with a hardware manual in hand. If hardware designers and documenters were to invent and use naming conventions that suited programming languages, and programming languages had some facility such as C’s enum but with stronger typing, then I would not need to continuously reference the header files in addition to the hardware manual. I think that this requires coordinated language design and development of engineering practice. I don’t hold out much hope. Some development environments can in just a few mouse clicks quickly show the output of the pre-processor. Such a facility greatly reduces my objections. Unix is not one of those environments! There is an “iron man” ethos about that only sissies need hardware manuals and that header files should really suffice. This goes with the practice that hardware concepts are spread by oral tradition and that only such details as bit ordering cannot be remembered and are thus relegated to header files.