3

It's known that the MOV instruction allows register to register moves while memory to memory moves are not possible. Why is this?

I've read here that memory to memory moves are disallowed because it complicates the CPU and that RAM has to be in either a read mode or write mode with any given instruction. Is anyone able to expand on this? Why does RAM have to be in either read mode and write mode? How is it possible to read and write from registers but not from RAM within a single instruction?

6
  • 2
    With the movs[b/w/d] instruction it is possible for to copy a byte, a word, or a dword from one memory location to a another memory location. x86.renejeschke.de/html/file_module_x86_id_203.html Commented Aug 9, 2015 at 14:08
  • It's juste the write that makes the thing complicated as it should be atomic. Search for read-modify-write. Commented Aug 9, 2015 at 14:12
  • 8
    In case of x86 the actual reason is that the instruction encoding simply has no space for two memory (effective address) operands. The workaround is that some instructions have implicit operands, such as the MOVS mentioned above or even PUSH/POP, and those can do memory-to-memory copies. Commented Aug 9, 2015 at 14:13
  • @Jester So how does the MOVS instruction encoding represent that it has implicit operands? From reading link , it suggests that the reg2 field in the ModR/M section is always treated as the register and does not take the actual address inside the register. Commented Aug 9, 2015 at 15:10
  • MOVS does not use modrm at all, it doesn't have explicit operands. It's a single byte opcode, and the cpu knows to use ESI/EDI automatically (that's why it's implicit). Commented Aug 9, 2015 at 15:16

1 Answer 1

3

Because Intel designed it that way, and having the flexibility to encode or [di], [si] would have made the instruction longer even when you were using or al, [si].

What you read about read or write mode doesn't make sense, because or [rdi], rax does a read-modify-write. So there always were instructions that did both, even apart from the few instructions that could read one location and write another (see below).

When Intel designed x86, they decided to limit the complexity of instruction encoding by only allowing a choice of addressing modes for one operand per instruction. The other register operand is selected by 3 bits in the byte that also selects an addressing mode. (Or 3 bits as part of the opcode, or 3 bits stuffed somewhere else... current x86 instruction encoding has so many special cases...)

x86-64 added an extra bit to double the amount of registers, but didn't change anything fundamental. (It did add RIP-relative addressing, though.)

See links to Intel manuals from https://stackoverflow.com/tags/x86/info.

Most x86 instructions take one of these forms

op r, r/m32 op r/m32, r 

The r being one of the gp registers, and the r/m32 being a register or memory operand, depending on the addressing-mode.

The two versions are usually different opcodes, even though they share the same mnemonic. So from a hardware / machine-language POV, the memory source and memory dest versions are two separate instructions. mov itself has many different opcodes, for various special cases. (especially if you count move to/from control registers.)

As people note in comments, there are instructions that both read and write memory, with at least one of the operands having an implicit location not encoded in the usual mod/rm addressing mode encoding.

  • movs: string move. (don't use except with rep, it's super slow)
  • push r/m32 (e.g. push [rax]).
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.