CTSS: Assembly Language

I am not planning to go into too much detail on assembly language in this blog, but I will take a quick look at some of the features of the IBM 7x architecture that are different from what we are used to today, and the assembler available on CTSS.

/images/ctss/ctss-slip-assembly.png

Part of the assembly language listing of the SLIP library used in ELIZA. Source: Github jeffshrager/elizagen.org

The FAP assembler

The Fortran Assembly Program was used on batch operating systems to assemble FORTRAN compiler output and user assembly code. As mentioned in the article on early software, this was based on work one by individual 7x sites and eventually adopted by IBM as part of IBSYS and FMS. This code was ported to CTSS to run interactively and used for most of the low level operating system code.

Although the opcodes and operands are hardware specific, the format of code as shown above would be familiar to machine code programmers today, with labels on the left followed by instructions in column 8, and then optional comments.

To assemble name1 fap on CTSS, use the command FAP name1. It takes the optional argument (LIST) if you want to produce a listing, and (SYMB) to produce a symbol table for debugging.

The instruction set architecture

1s complement

The 7x uses 1s complement for quantities and arithmetic, so that the left most bit of a word is 0 for positive and 1 for negative. This has some interesting consequences such as there existing a +0 which is different from -0.

Word addressing

Access to memory is via words; there is no concept of byte or sub-word addressing.

Not many general purpose registers

There is really only the accumulator as a general purpose register. There is a multiplier/quotient register that is used when multiplying two words together where the extra space is needed. But most operations involve bringing data in from memory and applying it to the accumulator.

Index registers

/images/ctss/7094-sample-instruction.png

Arrangement of fields in a sample instruction. Source: IBM 7094 Principle of Operations at bitsavers.org

To aid with constructs like looping, there are 3 index registers on the 7090 and 7 on the 7094. These are selected by means of a 3 bit tag field in many instructions (shown as T above): on the 7090 you can select multiple index registers at once, on the 7094 you can do multiple selection for index registers 1-3 or select any single register from 1-7 depending on the mode of the machine.

Index registers are effectively 15 bits wide, as 2¹⁵ = 32k is the maximum memory space.

The contents of the selected index register(s) are subtracted from the address specified rather than added. This leads to tables of values being naturally stored in descending order of memory location, for example Fortran II does this for arrays. It is however possible to get the contents of the index registers to be added by storing a 2s complement value in a index register.

Indirect addressing

Setting the Flag field (F in the above) indicates indirect addressing. The CPU goes to the address indicated in the instruction, loads the value there and then treats that as an address to load the final value from.

Calling convention

There is no stack register on this CPU, so a different method is needed for calling subroutines. For a single parameter/return you could use the accumulator, but for more than one the convention used was to place the parameters in the program's memory just after the call instruction, use index registers to access these from the subroutine and then jump back to a fixed location after the callee and parameters. (frobenius.com has a great example of how this works in detail.)

Supervisor calls are done by branching to a subroutine whose first instruction is TIA and contains in the address field the BCD formatted name of the system call. The machine will trap into an exception where the supervisor can recognise it and take action.

Further information

All the below are on bitsavers. The IBM Principles of Operation describes the architecture and opcodes for the 7094. This should be read before the FAP manual on how to run the assembler. James Saxon's 1964 book Programming the IBM 7090 may be an easier way to learn assembly as it is structured as a series of lessons.

Questions, corrections, comments

I welcome any questions or comments, and also especially any corrections if I have got something wrong. Please email me at rupert@timereshared.com