TL;DR
It's all about getting systematic, easy to memorise mnemonics, which may reflect some underlaying structure, but most important ease practical use. Exact language is not always a handy one - except you're asking a lawyer :)
So why call the instruction "move"?
Oh, the age old copy-vs-move question. A beloved friend :)
There are many different, equally plausible explanations, but before going into any it's quite important to keep in mind, that naming is not so much about being exact as being descriptive and distinctive. Also, meanings and usage evolves over time. And last but not least, people use terms they learned first.
It as well depends on the features a computer offers, like if it is a generic two address machine or restricted to certain transfers - which may as well result in other alternative, often forgotten here: Load/Store (*1) instead of Copy or Move. In a more generic view, they are all transfers - a word not really implying anything about what happens to the source (*2).
And, as with many items in computer history, the IBM /360 is deeply entrenched in the development of Move vs. Copy as well.
(points in no specific order)
Machine Structure
The copy issue usually only comes up when a machine offers more than a single accumulator. For example the Manchester Baby didn't have any mnemonics in today's notation, but as a single accumulator design some documentation used Load and Store for data transfer between accumulator and memory. A quite clear syntax - then again, not hard for a 7 instruction CPU :)
Then again, it's easy to complicate even a simple machine like that. The ERA/Atlas (Univac 1101) design(s) tried hard to confuse everyone by using a plethora of terms for transfers:
- Insert for memory (or Q) to accumulator (or Q),
- Replace for accumulator to memory,
- Transmit for accumulator to Q and,
- Store for Q (or lower half of A) to memory.
The Siemens 2002, a single accumulator machine, like the Baby and the ERA/Atlas, simplified it to an all covering Transfer for register/memory transfers ... well, plus Load to for bringing immediate values into registers (*3).
Machine operation
It can depend on the view designers had on the machine. Is it some 'fast' parts, like registers, handling temporary items that get loaded and stored, or how memory works. In fact, with core memory, data really got moved, as the original content was destroyed due the read operation and had to be restored.
Easy Recognition
Copy quite easy collides with compare when using the usual way of 'compacting' words by leaving out vowels. CP vs. CMP is rather close creating potential confusion. For machines not using the Load/Store metaphor, Move gives an easy way out, which brings...
Unique 'Encoding'
While the IBM 1401 forced the user to use single character symbols for instructions, it became already in the 1950s standard to name instructions in a way that the first letter of a mnemonic signals the general meaning or grouping, while the follow up letter(s) are used to specify variations (like L -> Load and LH -> Load Halfword) or to add readability.
Siemens 2002 and IBM /360 are great examples here as they both used that scheme throughout. On the /370 Load/Store as well as Move was used, depending on source/target. It works like this:
A* -> Add
B* -> Branch
C* -> Compare
...
L* -> Load to register from register/memory
M* -> Memory to memory move
ST* -> Store register to Memory
The collision between add and and was solved by using N* for and-instructions.
Conclusion:
It was always more about having a nice decodable set of mnemonics than be super clear on the semantic side - after all, new usage creates new semantics, independent of prior application.
And then there is x86 History.
Where it All Started: Datapoint 2200
The Datapoint 2200 was developed by CTC as a tool to replace card based terminals (*4). Thus the language used for their assembler was somewhat /360 orientated, with transfer instructions called Load as they happened only between registers. In this context memory addressed by the memory pointer was just a special case. In fact, except for Jumps and Calls, the 2200 did not feature any memory addressing at all. For any random access H and L had to be loaded with separate 8 bit transfers. Further all mnemonics were created to directly represent an opcode, so each transfer had its own depending on source and destination (*5):
LA # -> Load A with immediate #
LB # -> Load B with immediate #
...
LAB -> Load A with B
LBA -> Load B with A
...
LAM -> Load A with Memory (addressed by HL)
LBM -> Load B with Memory (addressed by HL)
...
LMA -> Load Memory (addressed by HL) with A
LMB -> Load Memory (addressed by HL) with B
...
While an according assembler is thus straight forward and can be quite small (*6), this led to a 'mnemonic cloud' of 59 valid mnemonics for what most would considered a single or as maximum 4 different (*7) instructions.
Making it Smaller: Intel 8008
Intel's 8008 is a (mostly) straight forward implementation of the Datapoint 2200. No change so far compared to the Version 1 of the 2200.
Extending the Design: Intel 8080
The 8080 is a greatly enhanced version of the 8008. Most important due the addition of some 16 bit features (INX, DCX, DAD, LHLD, LXI, ...) or direct use of 16 bit addresses for other than Jump/Call (LDA, STA, SHLD, LHLD). In turn Intel simplified the mnemonic landscape by unifying all of the L** instructions into just two MVI
for immediate to register and MOV
for register to register (*8) transfer. Which register to be used was now encoded as parameters:
8008 8080
==== ====
LA # -> MVI A,#
LAB -> MOV A,B
LAM -> MOV A,M
LMB -> MOV M,B
...
It's easy to see that this is just a more verbose but still stringent 1:1 relation between a source line and the opcode to be generated. Intel still stopped not only short of integrating the new instructions into the MOV
semantics, but even stayed back to use a single mnemonic for the new memory pointer access instructions or the direct load/stores which are at least in itself symmetric. So while cutting off 57 mnemonics, 6 more were clamped on.
Sidestep in Time Line: Zilog Z80
It seems, that the Z80 designers still had an eye on the Datapoint 2200 when designing their new CPU. Not only did they add a second register set, much like the 2200 Type 2, but they also went back to use Load to name all transfer instructions (*10). Just this time all the way with sensible parameter detection. So not only all 8080 MOV
became LD
, but all the separate mnemonics for other transfers were brought in line:
8008 8080 Z80
==== ==== ===
LA # -> MVI A,# -> LD A,#
LAB -> MOV A,B -> LD A,B
LAM -> MOV A,M -> LD A,(HL)
LDAX B -> LD A,(BC)
STAX D -> LD (DE),A
STA adr -> LD (adr),A
LHLD adr -> LD HL,(adr)
Zilog did not only straighten up all transfers, but as well moved conditionals out of the opcode column for all Calls, Jumps and Returns. While not being any result of the improved CPU itself, but a more capable assembler, it was quite used as argument to advertise how much more advanced and comfortable the new CPU was compared to its predecessor :)) (*10)
The End of All Future: Intel 8086
The 8086 was developed as a stop gap measure until the i432 was ready, with a clear focus on existing 8080 users needing an upgrade. Its designers took the same step as Zilog did, but being used to MOV
as the generic instruction for data transfer they stayed with it - but now covering every variation. After all, with the huge number of varying addressing modes and data sizes, a simple one mnemonic one opcode with a hack for RI and RR decoding couldn't do it anymore.
And the rest is history, as they say.
Postscript
What I like about the question is that it leads to a core issue of our age: Real vs. Virtual world. Our language developed over millennia to describe physical objects that can only exist once, with a certain uniqueness - copying is an extraordinary process involving much effort. In the digital age, copying isn't special, but the very base of everything. Not only every data item gets copied uncountable times until it's displayed, but already the software doing so is a copy moved into memory from some storage, to be moved into the CPU to be executed.
Our legal system(s) are badly torn when trying to judge the use of software and data (aka content) in terms of physical items, when they are in reality much more like a spoken word.
Next to everything still struggles to handle this, language usage being right at the core and this question pointing to it.
*1 - Which then again opens the question what loading does to 'the item'.
*2 - Again, but less, as a transfer paper adds copies, while a transfer ticket allows to use another transport.
*3 - Well, (next to) all assembler instructions were in German, so TAS
spelled out Transferiere AR in Speicherzelle - literally: Transfer AR (accumulator register) to Storage (memory) cell.
*4 - Back then a terminal wasn't a thing on your desk, but anything remote connected to a mainframe - like a card reader in some branch office where all transactions keypunched during the day were unloaded to be read remotely.
*5 - So at the very start 80 style assembler looked much more like later Motorola/MOS sources :))
*6 - Every OP is a 1:1 encoding of the mnemonic, so it's a straight lookup in a 4 byte table. Operands are only possible for certain opcodes and come in only two flavours: 8 bit immediate and 16 bit address.
The resulting assembler was small enough to run on the machine itself, with as low as 4 KiB memory.
*7 - Immediate, Register/Register, Memory/Register, Register/Memory
*8 - Including, like before, a memory cell addressed by HL as M.
*9 - It is sometimes said this was for copyright considerations, but it's hard to justify this in any way, as it wasn't just a renaming, but a complete reorganisation of the mnemonics as well as the assembly syntax. Also, descriptive names and sensible abbreviations thereof can't be trademarked or copyrighted in any country. If at all, the architecture might qualify - or the binary representation of opcodes, something DEC tried, without much success, for the VAX instruction set.
*10 - The Game Boy uses a LR35902 is a great example how a mostly 8080 like CPU can gain from just using Z80 syntax. Likewise when restricting Z80 assemblers to 8080 features.