MOV is the Intel 8080 and x86 Assembly instruction to load in a register the value of another register. Why did they call it move, instead of copy or load, if the value of the source register is not deleted or changed?
Zilog pretty much had to call it load in the Z80 to reduce IP issues but I wonder about the original rationale.
Interesting - almost archaeology and etymology. Coming from 6502, very nearly an accumulator machine, I’m used to load and store. It puts me at the MPU, with the memory more distant, and gives a good feeling whether data is coming towards me or going away from me.
The 6502 also has a small number of transfer instructions for moving data between registers.
The mnemonics are such that they include the register names: STA, LDX, TXS.
But once you’ve got a lot of registers, for purposes of training and of writing an assembler, you might want to simplify and regularise. I never quite liked the Z80’s use of LD for everything, including stores.
So, MOV might be a good solution to both training and assembler. Seems the 68k did the same, from a quick search.
The choice of mnemonics may been developed because of software limitations. The early 3 letter mnemonics may have been easy for a FORTRAN cross assembler to parse.
I had the TEA: AN 8080 8085 CO-RESIDENT EDITOR/ASSEMBLER book, and layout was strange to save memory.
I find the most confusing thing, when swapping between different assemblers, is that some of them have the destination first, followed by the source, and others have it the other way round.
For some addressing modes, it’s pretty obvious from the context which way the transfer/copy/load/move is going to occur, but a simple instruction like:
mov r1, r2
could mean completely different things to different assemblers.
I don’t think that destructive register operations are related to this. This was really a thing with the PDP-8 and its just 2 instruction bits and the need for a tight instruction set. Hence, destructive register operations saved dedicated clear instructions. I don’t think that this had ever been an issue for any 8-bit architecture, since you have per definition (at least) 8 instruction bits. As destructive operations are about trading runtime instruction count for the bit count of the instruction set, this wouldn’t make much sense for an 8-bit architecture.
So, where may we look for? Let’s have a look at the Datapoint 2200 (famously featuring the processor Intel was commissioned to implement on a chip, which became the 8008): here, we have a LOAD instruction (LRdRs). Same with the Intel 8008 and its first syntax as introduced in 1972: LRdRs. But with the advent of the 8080, which introduced MOV Rd,Rs, this was backported to the 8008 and changed to .MOV Rd,Rs, as well.
So MOVE was specifically introduced with the 8080. One guess may be that this change was related to the very concept of how the CPU related to memory. The processor of the DP 2200 was built around an early Intel shift register for memory, meaning sequential access. Memory was slow and distant, thus the need for a multitude of internal registers to minimize memory access. This carried over to the 8008, which was essentially the same ISA. The major change with the 8080 was that this was now adapted for modern RAM, This resulted in a directer and faster memory and I/O access, which must have revolutionized how memory was thought about. Maybe, MOVE was introduced to highlight this direct access, which was now much more like the orthogonal architecture of the PDP-11? But, if so, why was this also immediately reapplied to the new syntax and mnemonics for the 8008, which was still the same as it ever was? While this ought to highlight the compatibility aspect, it also ruins the novelty aspect of direct RAM access, if this had been the original idea.
On the other hand, it may have been also just that LOAD had been already defined by CTC/Datapoint, and MOVEwas how Federico Faggin and/or Masatoshi Shima, now free from any predetermined concepts, liked to think about it.
As a third and final thought on this: maybe it’s really related to the internal architecture. The Datapoint 2200 initially featured an internal bit-serial design, which was copied for the 8008. When the 8008 eventually became ready, CTC/Datapoint had moved beyond this for a much faster bit-parallel design, which is also why the 8008 was rejected and how Intel wound up with the rights to the processor. This was also the other great improvement of the 8080, which was about 5 times faster thanks to this. So, maybe MOVE is related to this parallel move of the register contents? (And maybe also to distance this new design from the earlier, inherited architecture?)
Maybe something about this is found in any oral history related to 8080.
I think this would be key - when asking “why” we might find there are technical reasons, we might find marketing reasons, or arbitrary human choices. It’s fun to speculate but for a definitive answer we really need some kind of evidence from the past. Of course, oral histories are only a person’s telling of their own memories.
I see there were some nice answers to a similar question over on stackexchange:
I certainly agree that speculation is unlikely to land on the answer but it’s fun nonetheless.
It’s interesting that the 6800 and 6502 use “load”/“store” when talking about memory but “transfer” when going between registers. “transfer” feels equivalent to “move”. The 6809 continues with tradition with the “TRF r1,r2” transfer instruction which is really copying data. But it has the semantically correct “EXG r1,r2” to exchange the contents of registers. The Z-80 also as exchanges though it actually “renames” registers rather than move the contents around.
To do a “move” the source register is copied onto the internal bus and then the destination register is told to move data from the bus to itself. So there is a “move” action to be taken up into the mnemonic.
I suppose “move” is more correct when speaking of the data bus. After all, you’re not necessary loading and storing to memory. It is quite possible to store N to memory location K and then read back an entirely different value from K. All you’re doing is moving data to the bus (or from the bus) in a manner of speaking.
Or maybe they used “move” because “copy” would get confused with “compare” when abbreviated?
Continuing on this, DEC, in the early days, generally used the load/deposit paradigm. But, when it came down to individual bits, these got “jammed” into registers. I’m not aware that “jam” ever applied to any higher level as a general concept, but, of course, I don’t know every single instruction set, there is. (Also, I may just be ignorant. )
(There’s a class of undocumented/illegal opcodes on the 6502, which is sometimes labeled “JAM”, but as the terminology implies, this isn’t an official concept. Moreover, this is about a different concept of jamming, like in jammed gears, referring to the processor being stuck in a T-phase and delivering 0xFF on all ports until reset.)
I cannot think of jam, but several early textbooks 1960’s often had a CLEAR and ADD instruction.
Rarely did one have more than a AND and a Compliment for logic operations.
Some times a Deposit Zero could be a valid operation or other strange functions for BIT MAPPED
memory.
Ben.
The IMP77 language had a JAM concept where “larger” integer varianles could be JAM’ed into smaller integer variables, e.g a %long into a %short (or even a %byte). This was indicated by ← insread of =.
If larger variable (%long) has 4 bytes than the smaller (i.e. %short (2 bytes) or %byte (1 byte)) would have the %long lower (more insignificant bytes) “jammed” into the smaller range variables.
Thus if a %long had a value in the range -32768 to 32767 and was jammed into a %short there would be effectively no change in “value” when stored in the %short.
The “jam” concept also applied to IMP strings which are a byte counted array of ascii bytes. An IMP string is initially defined with a maximal size (1…255). This initial size cannot be increased. Thus an IMP string takes up at most 256 bytes. First (zeroth) byte holds the current string length. Copying a %string means copying the number of ASCII chars (bytes) specified by the string length (NOT it’s initial size)
Thus the longer string would effectively be truncated when being “jammed” into the smaller sized string.
Re: Demons v IMPs.
Lincoln (county town of Lincolnshire) has an IMP.
It’s a carving in the Lincoln Cathedral which also holds a copy of Magna Carta. Wikipaedia has an entry describing the carving.
I lived there for 6 years.
My own little fun OS written in BCPL calls background tasks Imps. The system call to create an Imp as a thread to the current task is: impusNatum() … (There is also impusPartum() to create a stand-alone task).
Nothing to do with Harry Potters use of Latin but everything to do with the game; Dungeon Keeper where you create Imps to do little tasks for you…
Back to Move vs. Copy… I did ponder this for a while (and asked elsewhere) about it in the case of the 6502 where we Load data from memory to a register (or Store from register to memory) but we Transfer from register to register. Maybe in ye-olde days of core memory something, somewhere could do the move without refreshing the core memory location, thus losing it forever and making it a real move… and it just stuck?
Sounds a bit tricky to setup, but a good idea for a OS.
Transfer or move may be used to indicate internal logic, with load and
store for external memory.
Some computers that had index registers
having no opcode space to load or store a index register would
have them mapped to low memory, so index n is memory location n
as well getting a index resister almost for free.