pop

Stackosaurus

PDP-11 Architecture

PDP-11 Overview

In the days before the microcomputer revolution, Digital Equipment Corporation's (DEC's) PDP-11 was one of the most popular minicomputers of all time. It was introduced in 1970 and production continued into the early 1990s. By the end of production, DEC had sold over half a million of these machines according to Wikipedia.

The PDP-11 was a 16-bit computer. It embraced the 8-bit byte and used the ASCII character set. Today, 8-bit bytes and ASCII (and Unicode!) are taken for granted, but back then there were 9-bit bytes, 6-bit characters, and a jumble of other encodings on various computers. DEC still used EBCDIC for 80-column punched cards for compatibility with IBM card punch machines.

The 16-bit architecture had a natural 216 address space, which is 64 kbytes. Some models used an "extended memory" model of 18 bits, or 256 kbytes. The PDP-11 Unibus bus architecture also provided an 18-bit address space. Later models (such as the hefty PDP-11/70) increased this to a 22-bit address space, or 4 Megabytes.

The PDP-11 used memory-mapped input/output (I/O). The top 8 kbytes of the address space was reserved for device control and data registers, and for other special-purpose registers.

PDP-11 Operation Codes ("Op Codes")

The PDP-11 had eight base registers, numbered 0 through 7. Register 6 was used as a stack pointer for operations such as subroutine calls. Register 7 was the Program Counter (PC), and would increment by 2 with each instruction word it fetched.

The PDP-11 also had eight addressing modes. The most fundamental mode was Register Mode, in which an instruction would access the contents of one of the eight registers. Autoincrement mode would access the contents of a register, then increment the register. Autodecrement mode would decrement a register, then access the contents of the register. Index mode would add the value of the next word to the register.

When used together, the PDP-11's post-increment and pre-decrement modes could manipulate stacks. Pre-decrement mode could push a value on a stack, and post-increment could access the value on the top of the stack, then pop the value off the stack by incrementing the stack pointer. Thus the stack model in the PDP-11 grew from the top downwards. Index mode could reference array elements.

The four modes mentioned above were followed by an "indirect" bit, which if set would use the result of the register access as the address location of the data for the operation. These three bits thus provided eight addressing modes.

The table below shows these modes with their meaning and assembly language syntax. Rn refers to one of the general purpose registers, R0 through R7. The index value i refers to a 16-bit index value.

Binary
Op Code
Addressing ModeSyntax
000Register Rn
010Autoincrement (Rn)+
100Autodecrement -(Rn)
110Index i(Rn)
Binary
Op Code
Addressing ModeSyntax
001Register Indirect @Rn
011Autoincrement Indirect @(Rn)+
101Autodecrement Indirect @-(Rn)
111Index Indirect @i(Rn)

Part of the magic of the PDP-11 was that the Program Counter (PC) was a general purpose register, R7. This allowed it to be manipulated like any other general purpose register. Such manipulation of the PC provided capability for immediate data, absolute memory location references, and relative memory location references. The table below shows these modes with their meaning and assembly language syntax. The value n refers to a 16-bit value.

Binary
Op Code
Addressing ModeSyntax
010Immediate #n
110Relative Direct @#n
Binary
Op Code
Addressing ModeSyntax
011Absolute Direct n
111Relative Indirect @n

As an example, consider Immediate Mode. When an instruction is fetched, the Program Counter, R7, is incremented by two. It is then pointing to the word that follows the current instruction. The instruction is then executed. If the instruction accesses the location pointed to by R7, then increments R7, that instruction uses the word that immediately follows the current instruction and increments the Program Counter by 2 again so it points to the 16-bit word that follows. Program execution then continues by fetching the instruction after the immediate value.

Machine Instruction Format

The general format of a PDP-11 machine instruction with one op code and two operands (a source and a destination) is:

15141312 1110 9 8 7 6 5 4 3 2 1 0
Op Code Source Destination

An operand in a two-operand instruction would consist of a 3-bit addressing mode followed by a 3-bit register number. Because of this, it was natural to express PDP-11 machine instructions using octal numbers. So for example, an instruction to move (binary op code 0001 or octal op code 01) the contents of R3 to R5 would be encoded as

Octal
Machine Code
Assembly Language
010305
MOV R3,R5

An instruction to move the immediate value "6" to R4 would be encoded as

Octal
Machine Code
Assembly Language
012704
MOV #6,R4
000006
 

The Processor Status Word (PSW)

The Processor Status Word (PSW) resides at the highest memory location, octal 777 776 on a machine with and 18-bit address space. The table below shows its layout:

15141312 1110 9 8 7 6 5 4 3 2 1 0
Mode Information Unused Priority T N Z V C

These fields are as follows:

Instructions such as conditional branches use the NZVC fields in the same order as they appear in the PSW.

Op Codes

The PDP-11 had op codes that took two operands, one operand, and no operands (such as a "HALT" instruction).

Processor Status Word (PSW) Instructions

Several machine instructions manipulate the PSW. There are op codes to set and clear one condition code at a time (N, Z, V, or C). Machine instructions exist that could clear any combination of these bits or set any combination of these bits in the same instruction. The general format of these instructions is:

Format

  15141312 1110 9 8 7 6 5 4 3 2 1 0
Clear
0 000 000 010 10
NZVC
Set
0 000 000 010 11
NZVC

The list of instructions related to the PSW follows (op codes that manipulate the Mode Information bits are not listed):

Octal
Op Code
Assembler
Mnemonic
Explanation
000240
 NOP
No Operation; Clear no condition code bits.
000241
 CLC
Clear Carry bit.
000242
 CLV
Clear Overflow bit.
000244
 CLZ
Clear Zero bit.
000250
 CLN
Clear Negative bit.
000257
 CCC
Clear Condition bits (i.e., all four of them).
000261
 SEC
Set Carry bit.
000262
 SEV
Set Overflow bit.
000264
 SEZ
Set Zero bit.
000270
 SEN
Set Negative bit.
000277
 SCC
Set Condition bits (i.e., all four of them).
00023p
 SPL p
Set Priority Level to p (range: 0 – 7).

Branch Instructions

Branch instructions operate based on the status of the four condition bits in the PSW: N, Z, V, and C.

Format

15141312 1110 9 8 7 6 5 4 3 2 1 0
Op Code Offset

The Offset value is a two's complement offset from the current PC value. Because the branch op codes are 8 bits long, they are given below in binary rather than octal.

Binary
Op Code
Assembler
Mnemonic
Explanation
0 000 000 1
 BR
Unconditional branch.
0 000 001 0
 BNE
Branch if not equal to zero.
0 000 001 1
 BEQ
Branch if equal to zero.
0 000 010 0
 BGE
Branch if greater than or equal to zero.
0 000 010 1
 BLT
Branch if less than zero.
0 000 011 0
 BGT
Branch if greater than zero.
0 000 011 1
 BLE
Branch if less than or equal to zero.
1 000 000 0
 BPL
Branch if plus (i.e., not negative).
1 000 000 1
 BMI
Branch if minus (i.e., negative).
1 000 001 0
 BHI
Branch if higher than (C OR Z = 0).
1 000 001 1
 BLOS
Branch if lower than or same as (C OR Z = 1).
1 000 010 0
 BVC
Branch if overflow clear.
1 000 010 1
 BVS
Branch if overflow set.
1 000 011 0
 BHIS
 BCC
Branch if higher than or same as;
Branch if Carry clear.
1 000 011 1
 BLO
 BCS
Branch if lower than;
Branch if Carry set.

Other Execution Order Instructions

Other instructions that alter the order of instruction execution are listed below.

Octal
Op Code
Assembler
Mnemonic
Explanation
0001aa
 JMP aa
Jump to effective address aa.
000002
 RTI
Return from Interrupt;
Return from Trap.
000003
 BPT
Breakpoint Trap: Push PSW, PC onto (SP); PC = word at address 14, PSW = word at address 16. Used for debugging.
000004
 IOT
I/O Trap: Push PSW, PC onto (SP); PC = word at address 20, PSW = word at address 22. Used by operating system for I/O operations.
000006
 RTT
Return from Interrupt;
Return from Trap.
104000
to
104377
 EMT
Emulator Trap: Push PSW, PC onto (SP); PC = word from address 30, PSW = word from address 32. Used by operating system for emulation operations.
104400
to
104777
 TRAP
Trap: Push PSW, PC onto (SP); PC = word from address 34, PSW = word from address 36. Preferred over EMT for non-operating system use.
00020R
 RTS R
Return from Subroutine: PC = contents of R; R = SP; Increment SP by 2 (pop word from stack).
004Raa
 JSR aa
Jump to Subroutine: Decrement SP by 2; Store contents of R in SP; Move contents of PC (return address) to R; Jump to effective address from aa. See also RTS (Return from Subroutine).
077Rnn
 SOB Rnn
Subtract one from R; if result is not equal to 0, subtract 2 times nn from the PC.

Two-operand Op Codes

Format

15141312 1110 9 8 7 6 5 4 3 2 1 0
Op Code Source Destination

Except for ADD and SUB, these op codes operate in byte mode if the high-order instruction bit is set, and in word mode if the high-order instruction bit is clear.

Octal
Op Code
Assembler
Mnemonic
Explanation
01
 MOV
Move the word at Source to word at Destination.
11
 MOVB
Move the byte at Source to byte at Destination.
02
 CMP
Compare word at Source minus word at Destination.
12
 CMPB
Compare byte at Source minus byte at Destination.
03
 BIT
Bit test: word at Source AND word at Destination.
13
 BITB
Bit test: byte at Source AND byte at Destination.
04
 BIC
Bit clear: (NOT word at Source) AND word at Destination.
14
 BICB
Bit test: (NOT byte at Source) AND byte at Destination.
05
 BIS
Bit set: word at Source OR word at Destination.
15
 BISB
Bit set: byte at Source OR byte at Destination.
06
 ADD
Destination = Source plus Destination.
16
 SUB
Destination = Destination minus Source.

One-and-a-half-operand Instructions

Format

15141312 1110 9 8 7 6 5 4 3 2 1 0
Op Code Register Address

The one-and-a-half-operand instructions only have word forms, not byte forms. Although the "Register" field appears in the machine language before the "Address" field, the assembly language syntax always gives the "Address" field first and the "Register" field last, because the result is stored in the "Register" field; the destination is always written last in PDP-11 assembly language.

Octal
Op Code
Assembler
Mnemonic
Explanation
0070
 MUL
Multiply: Register = Register times Address.
0071
 DIV
Divide: Register = Register divided by Address.
0072
 ASH
Arithmetic Shift: Register = Register shifted by low-order 6 bits of Address; positive value for these 6 bits shifts left, negative value shifts right.
0072
 ASHC
Arithmetic Shift Combined: Register = Register shifted by low-order 6 bits of Address; positive value for these 6 bits shifts left, negative value shifts right.
0073
 XOR
Exclusive OR: Register = Register XOR Address.

Note that MUL, DIV, and ASHC return the result in Register if Register is odd, and in (Register, Register+1) if Register is even.

One-operand Instructions

Format

15141312 1110 9 8 7 6 5 4 3 2 1 0
Op Code Operand

Most of the one-operand instructions operate on a byte when the high bit of the instruction word is set, and operate on a 16-bit word when the high bit of the instruction is clear. The table below shows both formats in the same table entry.

Octal
Op Code
Assembler
Mnemonic
Explanation
0003
 SWAB
Swap Bytes in a word.
0050
1050
 CLR
 CLRB
Clear word or byte at Operand.
0051
1051
 COM
 COMB
Complement (one's complement) of word or byte.
0052
1052
 INC
 INCB
Increment word or byte at Operand by 1.
0053
1053
 DEC
 DECB
Decrement word or byte at Operand by 1.
0054
1054
 NEG
 NEGB
Negate (two's complement) word or byte.
0055
1055
 ADC
 ADCB
Add carry bit to word or byte, for multi-word addition.
0056
1056
 ADC
 ADCB
Subtract carry bit to word or byte, for multi-word subtraction.
0057
1057
 TST
 TSTB
Test word or byte and set condition codes accordingly.
0060
1060
 ROR
 RORB
Rotate word or byte Right by one bit, using Carry bit.
0061
1061
 ROL
 ROLB
Rotate word or byte Left by one bit, using Carry bit.
0062
1062
 ASR
 ASRB
Arithmetic Shift word or byte Right by one bit, using Carry bit.
0063
1063
 ASL
 ASLB
Arithmetic Shift word or byte Left by one bit, using Carry bit.
0067
1067
 SXT
 SXTB
Sign Extend, setting all bits in word or byte to the N flag value.

Zero-operand Instructions

There are a few remaining miscellaneous zero-operand instructions.

Octal
Op Code
Assembler
Mnemonic
Explanation
000000
 HALT
Halts the CPU and terminates Unibus transfers.
000001
 WAIT
Wait until an interrupt occurs. RTI (Return from Interrupt) in the interrupt service routine resumes execution at the instruction following the WAIT instruction.
000005
 RESET
Sends an INIT signal on Unibus for 10 milliseconds. This returns all devices to their power-up state.

Endian-ness

The PDP-11 reads bytes into memory in little-endian order. This allows ASCII strings of any length to be stored in memory in sequential order.


pop