50

The PDP-11's program counter was addressable in two ways: as a general purpose register or as a memory location.

Still, the PDP-11's instruction set included separate instructions for moving a new value into the PC. Did the designers not realise that the MOV instruction would have done the trick? Is there something I'm missing?

Omar and Lorraine
  • 38,883
  • 14
  • 134
  • 274
  • 12
    Probably not applicable in this case, but in some assembly languages you'll see different mnemonics being encoded to the same basic opcode, so it would be possible for JMP to be implemented as a MOV. – Russell Borogove Apr 13 '17 at 19:39
  • 2
    I have made the discovery, that the CP1600, which was modelled on the PDP-11, does exactly as @RussellBorogove says: the same bit-pattern in the opcode for MOVR also was used for JMPR and some others depending on what the source/destination registers are. – Omar and Lorraine Jul 06 '18 at 09:46

3 Answers3

52

MOV changes the N, Z and V flags according to the copied data. JMP doesn't do that. It means you can run e.g. arithmetic operations somewhere, then jump to another location for the compare routine.

Also JMP appears to be 1 cycle faster. The handbook says JMP takes 1 to 3 cycles while MOV take 0 to 4 - maybe because it doesn't set the flags.

psmears
  • 173
  • 4
wizofwor
  • 2,788
  • 2
  • 14
  • 38
  • 12
    Also worth noting that the PDP-11 was designed with a CISC philosophy, so having multiple subtly different instructions was not viewed as a design problem, but rather a Good Thing. – T.E.D. Apr 12 '17 at 14:00
  • 4
    @T.E.D.: CISC vs RISC relates more to whether a computer has a set or reduced instructions, or a set of complex instructions, than whether the set is large or small. The PDP-11 qualifies as CISC because a single instruction could IIRC fetch memory using a register with post-increment, use that resulting address to fetch another word, and then add the fetched value to another register--all in all a rather complicated sequence of steps for a single instruction. ARM has a large number of instructions, but each only requires a single ALU operation (not counting the program-counter increment). – supercat Apr 12 '17 at 15:30
  • 1
    @supercat - CISC designs during their heyday had a philosophy that you wanted to make things as easy as possible for (Assembly Language) programmers by giving them as many tools as possible in your instruction set, and by trying to make it higher-level for them (which is how you get Lisp-like queuing operations in instruction sets). – T.E.D. Apr 12 '17 at 15:47
  • 2
    @T.E.D.: Certainly designers CISC processors wanted to include a large number of instructions, but I don't think that's what "made" them CISC. Certainly many RISC processors have dedicated jump instructions even when the PC is accessible as a register, though I'm somewhat skeptical as to whether e.g. the ARM's jump and BL instructions were a good use of address space. By the time an instruction reaches the execution stage of the pipeline, the succeeding instruction will have been fetched, so I wonder if it might not have been more useful to say that if an immediate operand... – supercat Apr 12 '17 at 16:15
  • 6
    @supercat - True, but I never said any such thing. What I said was that it "was designed with a CISC philosophy". I don't believe the word (or concept of) CISC even existed back then. They just had the idea that they needed to design their instruction set to be of maximum use to Assembly-language programmers. It was only after the RISC idea came along and repudiated that philosophy that we retrospectively term such CPU's "CISC". – T.E.D. Apr 12 '17 at 16:19
  • ...[never mind] – supercat Apr 12 '17 at 16:22
  • 1
    CICS didn't have a philosophy of making things as easy as possible for assembly language programmers. Their philosophy was more oriented to making the instruction encoding as compact as possible while being as powerful as possible. That's why they had multiple instruction lengths, many addressing modes, lots of implicit operations (assumed registers, etc.) In fact these things made it harder for assembly language programmers - and compiler writers too - but paid off in smaller programs that executed well on the hardware of the day. (It's much easier to write assembly in a simpler ISA.) – davidbak Apr 12 '17 at 16:46
  • I will go on record as saying that if there's an objective difference between CISC and RISC, it's so minimal that it's essentially impossible to define objective rules that differentiate the two. For the most part, RISC was little more than an attempt at claiming that the same things people had been doing for decades was suddenly shiny and new. – Jerry Coffin Apr 12 '17 at 17:50
  • @JerryCoffin - considering the most "advanced" instruction sets at the time, for powerful machines (not controllers) - there are obvious differences between the VAX ISA and X86 ISA (not to mention the end-of-the line Nebula MIL-STD-1862A) on the one hand, and the MIPS on the other hand. Besides the instruction length, formats, and addressing modes, you talk in terms of how many pipelining stages and how much stage-to-stage locking between pipeline stage is necessary in the hardware. So, I disagree with you. – davidbak Apr 12 '17 at 18:19
  • @JerryCoffin - Yes, initially "RISC" was essentially a marketing term used to sell the SPARC CPU in the early 80's. But there definitely was a different set of design goals between the SPARC and our VAX-11 CPU we were using when SPARC came out, resulting in very different looking assembly instruction sets and tasks for the coder. The VAX actually had high-level list processing instructions (yes, data structures supported by a CPU). – T.E.D. Apr 12 '17 at 18:23
  • @davidbak - Oh, and I assume that was a typo. If you were really talking about CICS, that was sort of a super-OS running on IBM mainframes, used for database operations (at least where I worked). Today they call it "middleware". – T.E.D. Apr 12 '17 at 19:04
  • @T.E.D. - oh dang you're right. CICS - you programmed that in COBOL right? I remember reading - with astonishment! - an official IBM document that said "by the way, in your COBOL code, don't call EXIT as that will cause the entire multi-terminal instance of CICS to terminate!" I hope they eventually fixed that. I did mean CISC. – davidbak Apr 12 '17 at 19:40
  • @davidbak - According to the wiki it was language agnostic. I wouldn't have known, as us peon students couldn't afford time on an IBM. I just had a part time job feeding the damn thing tapes and keeping its batch files running. – T.E.D. Apr 12 '17 at 20:34
  • @T.E.D. I think it was originally for the MIPS, and only later SPARC (not that it matters much either way). Yes, the VAX was different from the SPARC. Long before that, the Control Data mainframe I programmed was a lot different from an IBM, and both of them were substantially different from a DECSystem 10--but that doesn't make one "Reduced" and another "Complex". The "Complex" moniker, especially, was nothing more than denigrating the competition. – Jerry Coffin Apr 12 '17 at 21:00
  • 1
    @JerryCoffin - Yup, a large amount of it was marketing. Although sales folks for their competitors soon realized that, if you didn't expand the names out, both acronyms sounded similar and equally impressive to most people. So they started selling normal old CPUs like M68Ks as "CISC technology" :-) – T.E.D. Apr 12 '17 at 21:32
  • How can MOV really take as few as 0 cycles? – Omar and Lorraine Feb 26 '19 at 08:33
49

Besides the flags, and differences in cycle count, the more important difference is that JMP x uses the effective address of x, while MOV x,R7 uses the value at x. In other words, there's one level less of indirection, similar to the LEA and MOV opcodes for the x86.

So JMP R1 faults, and JMP @R1 is equivalent to MOV R1,R7.

This means one can use JMP d(R7) for relative jumps with a full 16-bit displacement (BR d only has an 8-bit displacement, which is often not enough). In the same way, one can store the address of some block of code (library) in, say, R1, and use JMP d(R1) to jump to a fixed displacement inside this code block. All of this is not possible with a single MOV instruction.

It doesn't make sense to access a register via the memory mapped address instead of just using it directly, because accessing them this way would need one more word per instruction, and therefore is inefficient.

dirkt
  • 27,321
  • 3
  • 72
  • 113
  • IIRC, bulk register save-restore routines made use of the ability to address registers as memory. – Leo B. Apr 12 '17 at 20:15
  • I wonder if this architecture actually would let you execute code in register. I've already used one that allowed it. – Joshua Apr 13 '17 at 02:36
  • @Joshua: Not to my knowledge, and it would be really difficult to assign a meaning to multi-word instructions as the register only holds one word. That's much easier on architectures where a complete instruction always fits into a register. – dirkt Apr 13 '17 at 06:21
  • @Wilson: If you remember on which versions of the PDP-11 had that feature, I'd be very interested. Registers have 16 bits, instructions have up to three words with 16 bit, so I can't imagine how it could work. I know it works e.g. on the PDP-1 (XCT instruction), which had 18-bit instructions but 36-bit registers, and no multibyte instructions. – dirkt Apr 13 '17 at 10:49
  • 2
    @Wilson: I understand this to mean it executes code fetching from 17777xx, where the contents of the registers are memory mapped? That's different than executing "code in a register" in the sense of non-faulting JMP R1 or PDP-1 XCT: it still executes via reading from "memory". – dirkt Apr 13 '17 at 11:48
5

One more reason is that if you have JMP 2000 and your program is moved in memory 1000 (octal) bytes forward, you automatically have JMP 3000, as it remembers the offset, and not the exact address value. You can use an exact address with JMP this way: JMP @#3000. It will not change when the program moves.

So, relative addressing allows to run the same program, loaded into different memory areas without patching.

Anixx
  • 1,547
  • 13
  • 25