Designer | Digital Equipment Corporation |
---|---|
Bits | 16-bit |
Introduced | 1970 |
Design | CISC |
Type | Register–register Register–memory Memory–memory |
Encoding | Variable (2 to 6 bytes) |
Branching | Condition code |
Endianness | Mixed (little-endian for 16-bit integers) |
Extensions | EIS, FIS, FPP, CIS |
Open | No |
Successor | VAX |
Registers | |
General-purpose | 8 × 16-bit |
Floating point | 6 × 64-bit floating-point registers if FPP present |
The PDP-11 architecture [1] is a 16-bit CISC instruction set architecture (ISA) developed by Digital Equipment Corporation (DEC). It is implemented by central processing units (CPUs) and microprocessors used in PDP-11 minicomputers. It was in wide use during the 1970s, but was eventually overshadowed by the more powerful VAX architecture in the 1980s.
The smallest unit of addressable and writable memory is the 8-bit byte. Bytes can also be held in the lower half of registers R0 through R5.
16-bit words are stored little-endian with least significant bytes at the lower address. Words are always aligned to even memory addresses. Words can be held in registers R0 through R7.
32-bit double words in the Extended Instruction Set (EIS) can only be stored in register pairs with the lower word being stored in the lower-numbered register. Double words are used by the MUL, DIV, and ASHC instructions. Other 32-bit data are supported as extensions to the basic architecture: floating point in the FPU Instruction Set or long data in the Commercial Instruction Set are stored in more than one format, including an unusual middle-endian format [2] [3] sometimes referred to as "PDP-endian."
A 64-bit double precision floating point format is supported by the floating point processor option (FPP) for 11/45 and most subsequent models.
The PDP-11's 16-bit addresses can address 64 KB. By the time the PDP-11 yielded to the VAX, 8-bit bytes and hexadecimal notation were becoming standard in the industry; however, numeric values on the PDP-11 always use octal notation, and the amount of memory attached to a PDP-11 is always stated as a number of words. The basic logical address space is 32K words, but the high 4K of physical address space (addresses 1600008 through 1777778 in the absence of memory management) are not populated because input/output registers on the bus respond to addresses in that range. So originally, a fully expanded PDP-11 had 28K words, or 56 kbytes in modern terms.
The processor reserves low memory addresses for two-word vectors that give a program counter and processor status word with which to begin a service routine. When an I/O device interrupts a program, it places the address of its vector on the bus to indicate which service routine should take control. The lowest vectors are service routines to handle various types of trap. Traps occur on some program errors, such as an attempt to execute an undefined instruction; and also when the program executes an instruction such as BPT, EMT, IOT, or TRAP to request service from the operating system.
During the life of the PDP-11, the 16-bit logical address space became an increasing limitation. Various techniques were used to work around it:
|
The CPU contains eight general-purpose 16-bit registers (R0 to R7). Register R7 is the program counter (PC). Although any register can be used as a stack pointer, R6 is the stack pointer (SP) used for hardware interrupts and traps. R5 is often used to point to the current procedure call frame. To speed up context switching, some PDP-11 models provide dual R0-R5 register sets. Kernel, Supervisor (where present), and User modes have separate memory maps, and also separate stack pointers (so that a user program cannot cause the system to malfunction by storing an invalid value in the stack pointer register).
Most instructions allocate six bits to specify an operand. Three bits select one of eight addressing modes, and three bits select a general register.
The encoding of the six bit operand addressing mode is as follows:
5 | 3 | 2 | 0 | ||
Mode | Register |
In the following sections, each item includes an example of how the operand would be written in assembly language. Rn means one of the eight registers, written R0 through R7.
The following eight modes can be applied to any general register. Their effects when applied to R6 (the stack pointer, SP) and R7 (the program counter, PC) are set out separately in the following sections.
Code | Name | Example | Description |
---|---|---|---|
0n | Register | Rn | The operand is in Rn |
1n | Register deferred | (Rn) | Rn contains the address of the operand |
2n | Autoincrement | (Rn)+ | Rn contains the address of the operand, then increment Rn |
3n | Autoincrement deferred | @(Rn)+ | Rn contains the address of the address of the operand, then increment Rn by 2 |
4n | Autodecrement | −(Rn) | Decrement Rn, then use the result as the address of the operand |
5n | Autodecrement deferred | @−(Rn) | Decrement Rn by 2, then use the result as the address of the address of the operand |
6n | Index | X(Rn) | Rn+X is the address of the operand |
7n | Index deferred | @X(Rn) | Rn+X is the address of the address of the operand |
In index and index deferred modes, X is a 16-bit value taken from a second word of the instruction. In double-operand instructions, both operands can use these modes. Such instructions are three words long.
Autoincrement and autodecrement operations on a register are by 1 in byte instructions, by 2 in word instructions, and by 2 whenever a deferred mode is used, since the quantity the register addresses is a (word) pointer.
When R7 (the program counter) is specified, four of the addressing modes naturally yield useful effects:
Code | Name | Example | Description |
---|---|---|---|
27 | Immediate | #n | The operand is the next word of the instruction |
37 | Absolute | @#a | The address of the operand is the next word of the instruction |
67 | Relative | a | The address of the operand is the next word of the instruction added to the PC |
77 | Relative deferred | @a | The address of the address of the operand is the next word of the instruction added to PC |
The only common use of absolute mode, whose syntax combines immediate and deferred mode, is to specify input/output registers, as the registers for each device have specific memory addresses. Relative mode has a simpler syntax and is more typical for referring to program variables and jump destinations. A program that uses relative mode (and relative deferred mode) exclusively for internal references is position-independent; it contains no assumptions about its own location, so it can be loaded into an arbitrary memory location, or even moved, with no need for its addresses to be adjusted to reflect its location (relocated). In computing such addresses relative to the current location, the processor performed relocation on the fly.
Immediate and absolute modes are merely autoincrement and autoincrement deferred mode, respectively, applied to PC. When the auxiliary word is "in the instruction" as the above table says, the PC for the next instruction is automatically incremented past the auxiliary word. As PC always points to words, the autoincrement operation is always by 2.
R6, also written SP, is used as a hardware stack for traps and interrupts. A convention enforced by the set of modes the PDP-11 provides is that a stack grows downward—toward lower addresses—as items are pushed onto it. When a mode is applied to SP, or to any register the programmer elects to use as a software stack, the addressing modes have the following effects:
Code | Name | Example | Description |
---|---|---|---|
16 | Deferred | (SP) | The operand is on the top of the stack |
26 | Autoincrement | (SP)+ | The operand is on the top of the stack, then pop it off |
36 | Autoincrement deferred | @(SP)+ | A pointer to the operand is on top of the stack; pop the pointer off |
46 | Autodecrement | −(SP) | Push a value onto the stack |
66 | Indexed | X(SP) | This refers to any item on the stack by its positive distance from the top |
76 | Indexed deferred | @X(SP) | This refers to a value to which a pointer is at the specified location on the stack |
Although software stacks can contain bytes, SP is always a stack of words. Autoincrement and autodecrement operations on SP are always by 2.
The PDP-11 operates on bytes and words. Bytes are specified by a register number—identifying the register's low-order byte—or by a memory location. Words are specified by a register number or by the memory location of the low-order byte, which must be an even number. In most instructions that take operands, bit 15 is set to specify byte addressing, or clear to specify word addressing. In the lists in the following two sections, the assembly-language programmer appended B to the instruction symbol to specify a byte operation; for example, MOV became MOVB.
A few instructions, for example MARK and SOB, were not implemented on some PDP-11 models.
The high-order four bits specify the operation to be performed (with bit 15 generally selecting word versus byte addressing). Two groups of six bits specify the source operand addressing mode and the destination operand addressing mode, as defined above.
15 | 12 | 11 | 9 | 8 | 6 | 5 | 3 | 2 | 0 | ||||||
Opcode | Src | Register | Dest | Register |
Opcode | Mnemonic | Operation |
---|---|---|
01 | MOV | Move: Dest ← Src Note: Moving byte to a register sign-extends into bits 8-15 |
11 | MOVB | |
02 | CMP | Compare: Set-flags(Src − Dest) |
12 | CMPB | |
03 | BIT | Bit test: Set-flags(Src ∧ Dest) |
13 | BITB | |
04 | BIC | Bit clear: Dest ← Dest ∧ Ones-complement(Src) |
14 | BICB | |
05 | BIS | Bit set: Dest ← Dest ∨ Src |
15 | BISB | |
06 | ADD | Add: Dest ← Dest + Src |
16 | SUB | Subtract: Dest ← Dest − Src |
The ADD and SUB instructions use word addressing, and have no byte-oriented variations.
Some two-operand instructions utilize an addressing mode operand and an additional register operand:
15 | 9 | 8 | 6 | 5 | 3 | 2 | 0 | ||||||||
Opcode | Reg | Src/Dest | Register |
Where a register pair is used (written below as "(Reg, Reg+1)", the first register contains the low-order portion of the operand and must be an even numbered register. The next higher numbered register contains the high-order portion of the operand (or the remainder). An exception is the multiply instruction; Reg may be odd, but if it is, the high 16 bits of the result are not stored.
Opcode | Mnemonic | Operation |
---|---|---|
070 | MUL | Multiply: (Reg, Reg+1) ← Reg × Src |
071 | DIV | Divide: Compute (Reg, Reg+1) ÷ Src; Reg ← quotient; Reg+1 ← remainder |
072 | ASH | Arithmetic shift: if Src<5:0> < 0 then Reg ← Shift-right(Reg, -Src<5:0>) else Reg ← Shift-left(Reg, Src<5:0>) |
073 | ASHC | Arithmetic shift combined: if Src<5:0> < 0 then (Reg, Reg+1) ← Shift-right((Reg, Reg+1), -Src<5:0>) else (Reg, Reg+1) ← Shift-left((Reg, Reg+1), Src<5:0>) |
074 | XOR | Exclusive or: Dest ← Dest ⊻ Reg |
The high-order ten bits specify the operation to be performed, with bit 15 generally selecting byte versus word addressing. A single group of six bits specifies the operand as defined above.
15 | 6 | 5 | 3 | 2 | 0 | ||||||||||
Opcode | Src/Dest | Register |
Opcode | Mnemonic | Operation |
---|---|---|
0001 | JMP | Jump: PC ← Src |
0003 | SWAB | Swap bytes of word: Dest ← Swap-bytes(Dest) |
0050 | CLR | Clear: Dest ← 0 |
1050 | CLRB | |
0051 | COM | Complement: Dest ← Ones-complement(Dest) |
1051 | COMB | |
0052 | INC | Increment: Dest ← Dest + 1 |
1052 | INCB | |
0053 | DEC | Decrement: Dest ← Dest − 1 |
1053 | DECB | |
0054 | NEG | Negate: Dest ← Twos-complement(Dest) |
1054 | NEGB | |
0055 | ADC | Add carry: Dest ← Dest + C flag |
1055 | ADCB | |
0056 | SBC | Subtract carry: Dest ← Dest - C flag |
1056 | SBCB | |
0057 | TST | Test: Set-flags(Src) |
1057 | TSTB | |
0060 | ROR | Rotate right: Dest ← Rotate-right(Dest, 1) |
1060 | RORB | |
0061 | ROL | Rotate left: Dest ← Rotate-left(Dest, 1) |
1061 | ROLB | |
0062 | ASR | Arithmetic shift right: Dest ← Shift-right(Dest, 1) |
1062 | ASRB | |
0063 | ASL | Arithmetic shift left: Dest ← Shift-left(Dest, 1) |
1063 | ASLB | |
1064 | MTPS | Move to PSW: PSW ← Src |
0065 | MFPI | Move from previous I space: −(SP) ← Src |
1065 | MFPD | Move from previous D space: −(SP) ← Src |
0066 | MTPI | Move to previous I space: Dest ← (SP)+ |
1066 | MTPD | Move to previous D space: Dest ← (SP)+ |
0067 | SXT | Sign extend: if N flag ≠ 0 then Dest ← -1 else Dest ← 0 |
1067 | MFPS | Move from PSW: Dest ← PSW |
In most branch instructions, whether the branch is taken is based on the state of the condition codes. A branch instruction is typically preceded by a two-operand CMP (compare) or BIT (bit test) or a one-operand TST (test) instruction. Arithmetic and logic instructions also set the condition codes. In contrast to Intel processors in the x86 architecture, MOV instructions set them too, so a branch instruction could be used to branch depending on whether the value moved was zero or negative.
The high-order byte of the instruction specifies the operation. Bits 9 through 15 are the op-code, and bit 8 is the value of the condition code calculation which results in the branch being taken. The low-order byte is a signed word offset relative to the current location of the program counter. This allows for forward and reverse branches in code.
15 | 9 | 8 | 7 | 0 | |||||||||||
Opcode | C | Offset |
Opcode | C | Mnemonic | Condition or Operation |
---|---|---|---|
000 | 1 | BR | Branch always PC ← PC + 2 × Sign-extend(Offset) |
001 | 0 | BNE | Branch if not equal Z = 0 |
001 | 1 | BEQ | Branch if equal Z = 1 |
002 | 0 | BGE | Branch if greater than or equal (N ⊻ V) = 0 |
002 | 1 | BLT | Branch if less than (N ⊻ V) = 1 |
003 | 0 | BGT | Branch if greater than (Z ∨ (N ⊻ V)) = 0 |
003 | 1 | BLE | Branch if less than or equal (Z ∨ (N ⊻ V)) = 1 |
100 | 0 | BPL | Branch if plus N = 0 |
100 | 1 | BMI | Branch if minus N = 1 |
101 | 0 | BHI | Branch if higher (C ∨ Z) = 0 |
101 | 1 | BLOS | Branch if lower or same (C ∨ Z) = 1 |
102 | 0 | BVC | Branch if overflow clear V = 0 |
102 | 1 | BVS | Branch if overflow set V = 1 |
103 | 0 | BCC or BHIS | Branch if carry clear, or Branch if higher or same C = 0 |
103 | 1 | BCS or BLO | Branch if carry set, or Branch if lower C = 1 |
The limited range of the branch instructions meant that, as code grew, the target addresses of some branches would become unreachable. The programmer would change the one-word BR to the two-word JMP instruction from the next group. As JMP has no conditional forms, the programmer would change BEQ to a BNE that branched around a JMP.
SOB (Subtract One and Branch) is another conditional branch instruction. The specified register is decremented by 1, and if the result is not zero, a reverse branch is taken based on the 6 bit word offset.
15 | 9 | 8 | 6 | 5 | 0 | ||||||||||
Opcode | Reg | Offset |
Opcode | Mnemonic | Operation |
---|---|---|
077 | SOB | Subtract One and Branch: Reg ← Reg - 1; if Reg ≠ 0 then PC ← PC - 2 × Offset |
JSR calls a subroutine. A group of six bits specifies the addressing mode. The JSR instruction can save any register on the stack and load that register with the return address. Programs that do not need this feature specify PC as the register (JSR PC, address
) and the routine returns using RTS PC
.
If a routine is called with, for instance, JSR R4, address
, then the old value of R4 is pushed on the top of the stack and the address just after JSR (ordinarily, the return address) is placed in R4. However, the routine can gain access to values coded in-line by specifying (R4)+, or to in-line pointers by specifying @(R4)+. The autoincrementation moves past these data, to the point at which the caller's code resumes. In either case, such a routine specifies RTS R4
to return to its caller.
The JSR PC,@(SP)+
form, which exchanges the contents of PC with the top element of the stack, can be used to implement coroutines. Once a routine places the entry address of the coroutine on the stack, executing JSR PC,@(SP)+
saves PC on the stack and jumps to the coroutine. Both coroutines can then use additional JSR PC,@(SP)+
instructions to jump to the other coroutine wherever it left off. This lets the two routines swap control and resume one another at the point of the previous swap.
15 | 9 | 8 | 6 | 5 | 3 | 2 | 0 | ||||||||
Opcode | Reg | Src | Register |
Opcode | Mnemonic | Operation |
---|---|---|
004 | JSR | Jump to subroutine: -(SP) ← Reg; Reg ← PC; PC ← Src |
The value of PC
moved to Reg
is the address after the JSR instruction.
15 | 3 | 2 | 0 | ||||||||||||
Opcode | Reg |
Opcode | Mnemonic | Operation |
---|---|---|
00020 | RTS | Return from subroutine: PC ← Reg; Reg ← (SP)+ |
15 | 6 | 5 | 0 | ||||||||||||
Opcode | nn |
Opcode | Mnemonic | Operation |
---|---|---|
0064 | MARK | Return from subroutine, discard stack entries: SP ← SP + (2 x nn), PC ← R5, R5 ← (SP)+ |
MARK is used to delete parameters on the stack when exiting a subroutine. MARK is unusual in that it is placed on the return stack by the caller for later execution directly on the stack by the return routine. First, the caller pushes R5 on the stack. Next, up to 63 word arguments may be placed on the stack. The caller then adds the number of arguments to the MARK opcode and pushes that result on the stack. The value of SP is copied to R5. Finally, a JSR PC,address
is executed to call the subroutine. After executing its code, the subroutine terminates with an RTS R5
. This loads the value in R5 (pointing to MARK instruction on stack) into the PC and pops the caller's return address into R5. The MARK instruction is executed. MARK multiplies the number of arguments by 2, adds that to SP, deleting the arguments, and then returns to caller with the equivalent of an RTS R5
. The MARK instruction is rarely used as its convoluted operation can be replaced by an ADD to SP. [5]
15 | 9 | 8 | 7 | 0 | |||||||||||
Opcode | S | Operation Code |
Opcode | S | Mnemonic | Operation |
---|---|---|---|
104 | 0 | EMT | Emulator trap: -(SP) ← PS; -(SP) ← PC; PC ← (30); PS ← (32) |
104 | 1 | TRAP | General trap: -(SP) ← PS; -(SP) ← PC; PC ← (34); PS ← (36) |
15 | 0 | ||||||||||||||
Opcode |
Opcode | Mnemonic | Operation |
---|---|---|
000002 | RTI | Return from interrupt: PC ← (SP)+; PS ← (SP)+ |
000003 | BPT | Breakpoint trap: -(SP) ← PS; -(SP) ← PC; PC ← (14); PS ← (16) |
000004 | IOT | I/O trap: -(SP) ← PS; -(SP) ← PC; PC ← (20); PS ← (22) |
000006 | RTT | Return from trap: PC ← (SP)+; PS ← (SP)+ |
Vector | Condition |
---|---|
000000 | (Reserved) |
000004 | Illegal instruction, bus error, stack limit |
000010 | Reserved instruction |
000014 | BPT instruction, trace trap |
000020 | IOT instruction |
000024 | Power fail |
000030 | EMT instruction |
000034 | TRAP instruction |
000114 | Parity error |
000244 | Floating point exception |
000250 | Memory management fault |
15 | 0 | ||||||||||||||
Opcode |
Opcode | Mnemonic | Operation |
---|---|---|
000000 | HALT | Halt processor: Halt execution before next instruction |
000001 | WAIT | Wait for interrupt: Halt execution before next instruction; Resume execution at next interrupt handler |
000005 | RESET | Reset UNIBUS: Assert INIT on UNIBUS for 10 ms; All other devices reset to power up state |
15 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ||||||||
Opcode | 1 | S | N | Z | V | C |
Opcode | S | Mnemonic | Operation |
---|---|---|---|
0002 | 0 | Ccc | Clear condition codes: Clear codes according to N, Z, V, C bits |
0002 | 1 | Scc | Set condition codes: Set codes according to N, Z, V, C bits |
The four condition codes in the processor status word (PSW) are
Instructions in this group were what Digital called "micro-programmed": A single bit in the instruction word referenced a single condition code. The assembler did not define syntax to specify every combination, but the symbols SCC and CCC assembled an instruction that set or cleared, respectively, all four condition codes.
Clearing or setting none of the condition codes (opcodes 000240 and 000260, respectively) could effectively be considered as no-operation instructions. In fact, the NOP mnemonic assembled into 000240.
Over the life of the PDP-11, subtle differences arose in the implementation of instructions and combinations of addressing modes, though no implementation was regarded as correct. The inconsistencies did not affect ordinary use of the PDP-11.
The EIS is an option for the 11/35/40 and 11/03, and was supplied as standard on newer processors.
FIS is an option for the PDP-11/35/40 and 11/03. Single-precision floats are operated on a stack addressed by a register operand. The high-order 13 bits specify the operation to be performed. A three bit field specifies which register is used as the floating point operand stack pointer. Each float is two words and each floating point instruction operates on two floats, returning one float as a result. The selected stack pointer is incremented by a stride of 4 after each operation.
15 | 3 | 2 | 0 | ||||||||||||
Opcode | Reg |
Opcode | Mnemonic | Operation |
---|---|---|
07500 | FADD | Floating add: 4(Rn) ← 4(Rn) + (Rn), Rn ← Rn + 4 |
07501 | FSUB | Floating subtract: 4(Rn) ← 4(Rn) - (Rn), Rn ← Rn + 4 |
07502 | FMUL | Floating Multiply: 4(Rn) ← 4(Rn) × (Rn), Rn ← Rn + 4 |
07503 | FDIV | Floating Divide: 4(Rn) ← 4(Rn) ÷ (Rn), Rn ← Rn + 4 |
This was the optional floating point processor option for 11/45 and most subsequent models.
The Commercial Instruction Set, known as CIS or CIS11, adds string and binary coded decimal (BCD) instructions used by COBOL and DIBOL. It was implemented by optional microcode in the 11/23/24, and by an add-in module in the 11/44 and one version of the 11/74. [6]
Strings are represented by two 16-bit integers stored in any two of the general-purpose registers, or as two 16-bit values in subsequent locations in memory. One is designated "n", which is the length up to 64 kB, and the other "A", which is a pointer to the start of the character data in memory. Together, an n/A pair indicates the location and length of the string. The basic operations are MOVEC, MOVTC and MOVRC, which move the character data in memory from the location indicated in one n/A pair to the location in a second n/A, both in registers. MOVECI, MOVTCI and MOVRCI did the same but with the locations indicated by n/A pairs in memory instead of registers. In all of the move instructions, if the source is shorter than the destination, the destination is padded, if the source is longer, it is truncated. If either occurs, the processor status flags are used to indicate this. [6]
MOVEC/MOVECI simply copies the data from one location to another. MOVRC/MOVRCI reverses the original string into the destination. MOVTC/MOVTCI translates characters during copy using a 256-byte lookup table held in a third n/A pair, with the A pointing to the start of the table and the lower eight bits of n being a value used to fill the destination string if the source string is shorter. Translations use the source string's character values as index numbers and copy the value in the translation table at that index into the destination string. This can be used for EBCDIC to ASCII conversions by placing the corresponding ASCII character code for the mapped EBCDIC codes in the table. The character "E" is character 69 in ASCII and 197 in EBCDIC, so to convert EBCDIC to ASCII one would make a table of 256 bytes with a 69 in location 197. When MOVTC is called and sees a 197 in the original string, it will output 97 in the new string, performing the conversion. [6]
String comparisons are handled by CMPC, which sets the processor condition codes based on the results of comparing two strings. LOCC finds the first occurrence of a character in a string, while SKPC searches for the first character that does not match, used for trimming blanks at the start of strings, for instance. SCANC and SPANC are similar to LOCC and SKPC, but match any character in a masked character set. This can be used, for instance, to find the next occurrence of any line-breaking character like VT, LF or CR. Character sets are a table of 256 bytes, split into subsets. [a] These are similar to the translation tables with the lower eight bits of the first word forming a mask, and the second word pointing to the start of the table. The mask selects which of the subsets, up to eight, are part of the character set during comparisons. Using this system, one can define character sets like uppercase, lowercase, digits, etc. and then easily make a union via the mask, for instance, selecting the upper and lowercase subsets to produce the complete set of letters. [6]
CIS also includes a set of data types and instructions for manipulating BCD numbers. This data is also represented by two 16-bit registers or memory locations, with the second number being the A identical to the string case. The first word now contains four fields which describe the string representation of the data, which include packed and unpacked digits, handling the sign, and the length of the string, from 0 to 16 bytes. DEC referred to unpacked data, with one digit per byte, as "numeric strings". Using packed data, with two BCD digits per byte, a 16-byte string held BCD numbers up to 32 digits long. Instructions included ADDP/ADDN for packed and unpacked data, SUBP/SUBN, ASHP/ASHN (arithmetic shift) and CMPP/CMPN (compare). Available for packed data only are MULP and DIVP. CIS also includes a set of six instructions (CVT) to convert BCD numbers between packed and unpacked formats, as well as to and from binary values. [6]
A final set of instructions is provided to load two or three 2-word string descriptors to the internal registers, avoiding the need for multiple MOVs. [6]
The PSW is mapped to memory address 177 776, and can thus be processed like any data. Instructions found on all but the earliest PDP-11s give programs more direct access to the register.
On PDP-11s that provide multiple instruction spaces and data spaces, a set of non-orthogonal Move instructions give access to other spaces. For example, routines in the operating system that handle run-time service calls use these instructions to exchange information with the caller.
The following PDP-11 assembly source code is for a subroutine named TOUPPER
that converts a null-terminated ASCIIZ character string to upper case.
000000 000000 010046 000002 010146 000004 016600 000006 000010 112001 000012 001414 000014 120127 000172 000020 003373 000022 120127 000141 000026 002776 000030 142740 000040 000034 000766 000036 012601 000040 012600 000042 000207 | ; TOUPPER:; Scan a null-terminated ASCII string, converting; all alphabetic characters to upper case.;; Entry stack parameters,; [SP+2] = Address of target string; [SP+0] = Return address;TOUPPER:MOVR0,-(SP); Save some registersMOVR1,-(SP)MOV6(SP),R0; Get address of stringLOOP:MOVB(R0)+,R1; Get a characterBEQDONE; If zero, then doneCMPBR1,#’z ; Is it between a and z?BGTLOOP; If not, get next charCMPBR1,#’aBLTLOOPBICB#40,-(R0) ; If a-z, then make it A-ZBRLOOPDONE:MOV(SP)+,R1; restore registersMOV(SP)+,R0RTSPC; Return from subroutine |
The following PDP-11 assembly source code demonstrates how the PDP-11's addressing modes can be used to write the same routine with no general registers at all.
000000 000000 105776 000002 000004 001416 000006 127627 000002 000172 000014 003008 000016 127627 000002 000141 000024 002403 000026 142776 000040 000002 000034 005266 000002 000040 000757 000042 000207 | ; TOUPPER2:; Scan a null-terminated ASCII string, converting; all alphabetic characters to upper case.;; Entry stack parameters,; [SP+2] = Address of target string; [SP+0] = Return address;TOUPPER2:TSTB@2(SP); Test char at address on stackBEQDONE; If zero, then doneCMPB@2(SP),#’z ; Is it between a and z?BGTNEXTC; If not, point to next charCMPB@2(SP),#’aBLTNEXTCBICB#40,@2(SP) ; If a-z, then make it A-ZNEXTC:INC2(SP); Inc address of next char on stackBRTOUPPER2DONE:RTSPC |
PDP-11 processor speed varies by model, memory configuration, op code, and addressing modes. Instruction timings have up to three components, fetch/execute of the instruction itself and access time for the source and the destination. The last two components depend on the addressing mode. For example, on the PDP-11/70 (circa 1975), an instruction of the form ADD x(Rm),y(Rn) had a fetch/execute time of 1.35 microseconds plus source and destination times of 0.6 microseconds each, for a total instruction time of 2.55 microseconds. Any case where addressed memory is not in the cache adds 1.02 microseconds. The register-to-register ADD Rm,Rn can execute from the cache in 0.3 microseconds. Floating point is even more complex, since there is some overlap between the CPU and the floating-point processor, but in general, floating point is significantly slower. A single-precision floating add instruction ranges from 2.4 to 5.5 microseconds plus time to fetch the operands. [7]
The PDP-11 operates at a priority level from 0 through 7, specified by three bits in the Processor Status Word (PSW), and high-end models can operate in a choice of modes, Kernel (privileged), User (application), and sometimes Supervisor, according to two bits in the PSW.
To request an interrupt, a bus device asserts one of four common bus lines, BR4 through BR7, until the processor responds. Higher numbers indicated greater urgency, perhaps that data might be lost or a desired sector might rotate out of contact with the read/write heads unless the processor responds quickly. The printer's readiness for another character is the lowest priority (BR4), as it can remain ready indefinitely. If the processor is operating at level 5, then BR6 and BR7 would be in order. If the processor is operating at 3 or lower, it will grant any interrupt; if at 7, it will grant none. Bus requests that are not granted are not lost but merely deferred. The device needing service continues to assert its bus request.
Whenever an interrupt exceeds the processor's priority level, the processor asserts the corresponding bus grant, BG4 through BG7. The bus-grant lines are not common lines but are a daisy chain: The input of each gate is the output of the previous gate in the chain. A gate is on each bus device, and a device physically closer to the processor is earlier in the daisy chain. If the device has made a request, then on sensing its bus-grant input, it concludes it is in control of the bus, and does not pass the grant signal to the next device on the bus. If the device has not made a request, it propagates its bus-grant input to its bus-grant output, giving the next closest device the chance to reply. (If devices do not occupy adjacent slots to the processor board, "grant continuity cards" inserted into the empty slots propagate the bus-grant line.)
Once in control of the bus, the device drops its bus request and places on the bus the memory address of its two-word vector. The processor saves the program counter (PC) and PSW, enters Kernel mode, and loads new values from the specified vector. For a device at BR6, the new PSW in its vector typically specifies 6 as the new processor priority, so the processor will honor more urgent requests (BR7) during the service routine, but defer requests of the same or lower priority. With the new PC, the processor jumps to the service routine for the interrupting device. That routine operates the device, at least removing the condition that caused the interrupt. The routine ends with the RTI (ReTurn from Interrupt) instruction, which restores PC and PSW as of just before the processor granted the interrupt.
If a bus request is made in error and no device responds to the bus grant, the processor times out and performs a trap that suggests bad hardware.
MACRO-11 is the assembly language for the PDP-11. It is the successor to PAL-11 (Program Assembler Loader), an earlier version of the PDP-11 assembly language without macro facilities. MACRO-11 is supported on all DEC PDP-11 operating systems. PDP-11 Unix systems also include an assembler (called "as"), structurally similar to MACRO-11, but with different syntax and fewer features.
The Data General Nova is a series of 16-bit minicomputers released by the American company Data General. The Nova family was very popular in the 1970s and ultimately sold tens of thousands of units.
The 8086 is a 16-bit microprocessor chip designed by Intel between early 1976 and June 8, 1978, when it was released. The Intel 8088, released July 1, 1979, is a slightly modified chip with an external 8-bit data bus, and is notable as the processor used in the original IBM PC design.
The PDP-8 is a family of 12-bit minicomputers that was produced by Digital Equipment Corporation (DEC). It was the first commercially successful minicomputer, with over 50,000 units being sold over the model's lifetime. Its basic design follows the pioneering LINC but has a smaller instruction set, which is an expanded version of the PDP-5 instruction set. Similar machines from DEC are the PDP-12 which is a modernized version of the PDP-8 and LINC concepts, and the PDP-14 industrial controller system.
The PDP–11 is a series of 16-bit minicomputers sold by Digital Equipment Corporation (DEC) from 1970 into the late 1990s, one of a set of products in the Programmed Data Processor (PDP) series. In total, around 600,000 PDP-11s of all models were sold, making it one of DEC's most successful product lines. The PDP-11 is considered by some experts to be the most popular minicomputer.
In computing, endianness is the order in which bytes within a word of digital data are transmitted over a data communication medium or addressed in computer memory, counting only byte significance compared to earliness. Endianness is primarily expressed as big-endian (BE) or little-endian (LE), terms introduced by Danny Cohen into computer science for data ordering in an Internet Experiment Note published in 1980. The adjective endian has its origin in the writings of 18th century Anglo-Irish writer Jonathan Swift. In the 1726 novel Gulliver's Travels, he portrays the conflict between sects of Lilliputians divided into those breaking the shell of a boiled egg from the big end or from the little end. By analogy, a CPU may read a digital word big end first, or little end first.
In computer science, an instruction set architecture (ISA) is an abstract model that generally defines how software controls the CPU in a computer or a family of computers. A device or program that executes instructions described by that ISA, such as a central processing unit (CPU), is called an implementation of that ISA.
The Intel MCS-51 is a single chip microcontroller (MCU) series developed by Intel in 1980 for use in embedded systems. The architect of the Intel MCS-51 instruction set was John H. Wharton. Intel's original versions were popular in the 1980s and early 1990s, and enhanced binary compatible derivatives remain popular today. It is a complex instruction set computer with separate memory spaces for program instructions and data.
The Motorola 68000 series is a family of 32-bit complex instruction set computer (CISC) microprocessors. During the 1980s and early 1990s, they were popular in personal computers and workstations and were the primary competitors of Intel's x86 microprocessors. They were best known as the processors used in the early Apple Macintosh, the Sharp X68000, the Commodore Amiga, the Sinclair QL, the Atari ST and Falcon, the Atari Jaguar, the Sega Genesis and Sega CD, the Philips CD-i, the Capcom System I (Arcade), the AT&T UNIX PC, the Tandy Model 16/16B/6000, the Sun Microsystems Sun-1, Sun-2 and Sun-3, the NeXT Computer, NeXTcube, NeXTstation, and NeXTcube Turbo, early Silicon Graphics IRIS workstations, the Aesthedes, computers from MASSCOMP, the Texas Instruments TI-89/TI-92 calculators, the Palm Pilot, the Control Data Corporation CDCNET Device Interface, the VTech Precomputer Unlimited and the Space Shuttle. Although no modern desktop computers are based on processors in the 680x0 series, derivative processors are still widely used in embedded systems.
x86 assembly language is the name for the family of assembly languages which provide some level of backward compatibility with CPUs back to the Intel 8008 microprocessor, which was launched in April 1972. It is used to produce object code for the x86 class of processors.
Addressing modes are an aspect of the instruction set architecture in most central processing unit (CPU) designs. The various addressing modes that are defined in a given instruction set architecture define how the machine language instructions in that architecture identify the operand(s) of each instruction. An addressing mode specifies how to calculate the effective memory address of an operand by using information held in registers and/or constants contained within a machine instruction or elsewhere.
The Intel 8087, announced in 1980, was the first floating-point coprocessor for the 8086 line of microprocessors. The purpose of the chip was to speed up floating-point arithmetic operations, such as addition, subtraction, multiplication, division, and square root. It also computes transcendental functions such as exponential, logarithmic or trigonometric calculations. The performance enhancements were from approximately 20% to over 500%, depending on the specific application. The 8087 could perform about 50,000 FLOPS using around 2.4 watts.
The TMS9900 was one of the first commercially available, single-chip 16-bit microprocessors. Introduced in June 1976, it implemented Texas Instruments' TI-990 minicomputer architecture in a single-chip format, and was initially used for low-end models of that lineup.
In computer engineering, an orthogonal instruction set is an instruction set architecture where all instruction types can use all addressing modes. It is "orthogonal" in the sense that the instruction type and the addressing mode may vary independently. An orthogonal instruction set does not impose a limitation that requires a certain instruction to use a specific register so there is little overlapping of instruction functionality.
The Clipper architecture is a 32-bit RISC-like instruction set architecture designed by Fairchild Semiconductor. The architecture never enjoyed much market success, and the only computer manufacturers to create major product lines using Clipper processors were Intergraph and High Level Hardware, although Opus Systems offered a product based on the Clipper as part of its Personal Mainframe range. The first processors using the Clipper architecture were designed and sold by Fairchild, but the division responsible for them was subsequently sold to Intergraph in 1987; Intergraph continued work on Clipper processors for use in its own systems.
The TI-990 was a series of 16-bit minicomputers sold by Texas Instruments (TI) in the 1970s and 1980s. The TI-990 was a replacement for TI's earlier minicomputer systems, the TI-960 and the TI-980. It had several unique features, and was easier to program than its predecessors.
TLCS is a prefix applied to microcontrollers made by Toshiba. The product line includes multiple families of CISC and RISC architectures. Individual components generally have a part number beginning with "TMP". E.g. the TMP8048AP is a member of the TLCS-48 family.
Little Computer 3, or LC-3, is a type of computer educational programming language, an assembly language, which is a type of low-level programming language.
An instruction set architecture (ISA) is an abstract model of a computer, also referred to as computer architecture. A realization of an ISA is called an implementation. An ISA permits multiple implementations that may vary in performance, physical size, and monetary cost ; because the ISA serves as the interface between software and hardware. Software that has been written for an ISA can run on different implementations of the same ISA. This has enabled binary compatibility between different generations of computers to be easily achieved, and the development of computer families. Both of these developments have helped to lower the cost of computers and to increase their applicability. For these reasons, the ISA is one of the most important abstractions in computing today.
The PIC instruction set refers to the set of instructions that Microchip Technology PIC or dsPIC microcontroller supports. The instructions are usually programmed into the Flash memory of the processor, and automatically executed by the microcontroller on startup.
The WD16 is a 16-bit microprocessor introduced by Western Digital in October 1976. It is based on the MCP-1600 chipset, a general-purpose design that was also used to implement the DEC LSI-11 low-end minicomputer and the Pascal MicroEngine processor. The three systems differed primarily in their microcode, giving each system a unique instruction set architecture (ISA).