Mark Smotherman. Last updated September 2002.
The PDP-8 was the first mass-produced minicomputer. It was a 12-bit, word-addressed, accumulator-based design, first shipped in 1965. It was influenced by the CDC 160, the MIT Lincoln Labs LINC, and the DEC PDP-5.
Instructions are one 12-bit word each.
+-----+-+-+-------------+ | opc |i|p| offset | +-----+-+-+-------------+ 0 1 2 3 4 5 6 7 8 9 a b opc 3-bit opcode i 1-bit direct/indirect addressing mode p 1-bit global/current page for high address bits offset 7-bit offset effective address = p ? ( top 5 bits of last pc # offset ) : ( 00000 # offset );A notable feature of the PDP-8 was the lack of a load instruction. Instead, you would first clear the accumulator (cla) and then add the contents of a memory loaction to the accumulator (tad). The function of a store was done by the deposit and clear accumulator (dca) instruction. The PDP-8 did provide a fast loop-closing instruction, increment and skip if zero (isz), that did not use the accumulator. The isz instruction was also used as a general way to increment memory locations apart from its function in loops.
The jump to subroutine (jms) instruction stores the return address in the first word of the subroutine and starts execution with the second word (subr address + 1).
jms jump to subroutine memory[effective address] <- pc pc <- (effective address) + 1
Subroutine return is performed by an indirect jump using the address in the first word of the subroutine.
jmp i jump indirect pc <- memory[effective address]
Parameters are typically passed in-line after the jms instruction. The subroutine accesses the parameters via the stored return address, which it then increments so that it will point to the next instruction after the in-line parameters. A variable-length parameter list should start with a parameter count as the first in-line parameter.
... jms subr ! call with fixed number of parameters (two) parm1, 1 ! first in-line parameter parm2, 2 ! second in-line parameter ... ! subroutine will return here, after parms.
subr, 0 ! first word is reserved for return address cla tad i subr ! load indirect first word after jms inst. dca local1 ! and store in local variable isz subr ! increment address in subr tad i subr ! load indirect second word after jms inst. dca local2 ! and store in local variable isz subr ! increment address in subr ... body of subroutine ... jmp i subr ! return via first word local1, 0 ! local copy of first parameter local2, 0 ! local copy of second parameter
... jms subr jmp first_return_path jmp second_return_path ... subr, 0 ... body of subroutine ... ... if second_return path desired, then increment subr ... isz subr ... jmp i subr
To push the accumulator: DCA I SP / auto-increment SP prior to use To index off of SP by displacement X TAD (X) / load displacement TAD SP / add to stack pointer DCA 7 / store for use as indirect pointer To pop the top item off the stack into limbo: CLA CMA / load -1 (other negative constants will pop more) TAD SP / add to SP DCA SP / SP has been decremented(Thanks to Doug Jones for this section.)
[History of subroutines page] [Mark's homepage] [CPSC homepage] [Clemson Univ. homepage]