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.
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.
|
|
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.
|
|
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.
The general format of a PDP-11 machine instruction with one op code and two operands (a source and a destination) is:
15 | 14 | 13 | 12 | 11 | 10 | 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) resides at the highest memory location, octal 777 776 on a machine with and 18-bit address space. The table below shows its layout:
15 | 14 | 13 | 12 | 11 | 10 | 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.
The PDP-11 had op codes that took two operands, one operand, and no operands (such as a "HALT" instruction).
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
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |
Clear | 0 000 000 010 10 |
N | Z | V | C | |||||||||||
Set | 0 000 000 010 11 |
N | Z | V | C |
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 operate based on the status of the four condition bits in the PSW: N, Z, V, and C.
Format
15 | 14 | 13 | 12 | 11 | 10 | 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 |
Branch if higher than or same as; Branch if Carry clear. |
1 000 011 1 |
BLO |
Branch if lower than; Branch if Carry set. |
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. |
104000to 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. |
104400to 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. |
Format
15 | 14 | 13 | 12 | 11 | 10 | 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. |
Format
15 | 14 | 13 | 12 | 11 | 10 | 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.
Format
15 | 14 | 13 | 12 | 11 | 10 | 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 |
CLR |
Clear word or byte at Operand. |
0051 |
COM |
Complement (one's complement) of word or byte. |
0052 |
INC |
Increment word or byte at Operand by 1. |
0053 |
DEC |
Decrement word or byte at Operand by 1. |
0054 |
NEG |
Negate (two's complement) word or byte. |
0055 |
ADC |
Add carry bit to word or byte, for multi-word addition. |
0056 |
ADC |
Subtract carry bit to word or byte, for multi-word subtraction. |
0057 |
TST |
Test word or byte and set condition codes accordingly. |
0060 |
ROR |
Rotate word or byte Right by one bit, using Carry bit. |
0061 |
ROL |
Rotate word or byte Left by one bit, using Carry bit. |
0062 |
ASR |
Arithmetic Shift word or byte Right by one bit, using Carry bit. |
0063 |
ASL |
Arithmetic Shift word or byte Left by one bit, using Carry bit. |
0067 |
SXT |
Sign Extend, setting all bits in word or byte to the N flag value. |
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. |
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.