-2

I can do this:

mov eax, ebx

And this:

mov [eax], ebx

And even this:

mov eax, [ebx]

But not this (Error C2415):

mov [eax], [ebx]

Just wtf... Why? It the same as *ptr1 = *ptr2, why am I able to copy one register to another, copy value by addres in register to another register or copy value of register to address stored in another register...

But it cannot copy value on one address to another address. Why?

  • 5
    x86 processors don't support two memory operands for `mov`. Consult an instruction set reference and/or the basic architecture manual. To achieve what you want you need to go through a register. – Jester Feb 01 '19 at 15:32
  • 1
    Because CPU does not support it – Slava Feb 01 '19 at 15:33
  • This is what `*ptr1 = *ptr2` compiles to: https://godbolt.org/z/6xQhcR – tkausl Feb 01 '19 at 15:34
  • So basicly I need to do this: mov edx, [ebx] mov [eax], edx ... Right? – Georgiy List'ev Feb 01 '19 at 15:35
  • Also, you can reuse `ebx` if you don't need it, e.g. `mov ebx, [ebx]; mov [eax], ebx`. – Jester Feb 01 '19 at 15:37
  • Thanks, now It looks much more clear to me. – Georgiy List'ev Feb 01 '19 at 15:39
  • 2
    another duplicate: [Why isn't movl from memory to memory allowed?](https://stackoverflow.com/q/33794169/995714). See also [What x86 instructions take two (or more) memory operands?](https://stackoverflow.com/q/52573554/995714) – phuclv Feb 01 '19 at 15:54
  • 1
    Don't take assembly as "programming language", it's more like "names for CPU instructions", i.e. what is implemented in HW by the CPU vendor, that is available in assembler as instruction. There are some exceptions like having some helper macros or "pseudo-instructions" (one pseudo ins. gets transposed into multiple native instructions), but generally the mapping is 1:1, i.e. one instruction in source code text maps to one HW instruction recognized by CPU. If the CPU vendor doesn't provide `mov [eax],[ebx]`, the assembler can't do much about it (at least it reports error, some don't ;) ). – Ped7g Feb 01 '19 at 16:10
  • so reading every now and then through "instruction reference guide" is recommended, to refresh which instructions do exist, and what is their effect (also while writing actual code, you should probably check for each instruction details all the time, to be not surprised by some weird flag-setting rule, or implicit register usage, like `div ebx` expects 64 bit value in `edx:eax` to divide, and does produce about 2-3 questions monthly by people who don't read instruction manual and don't expect that). – Ped7g Feb 01 '19 at 16:13

3 Answers3

1

mov [eax], [ebx] would mean "move the contents of the memory location pointed to by ebx to the memory location pointed to be eax. That is a memory-to-memory move, which Intel does not support.

Paul Ogilvie
  • 25,048
  • 4
  • 23
  • 41
  • 1
    Note that while general memory-to-memory moves are not supported, some special cases (such as `push m32`) are supported. – fuz Feb 02 '19 at 12:10
1

You can't do mov [eax], [ebx] because that implies a machine instruction that will let you specify two memory operands. The x86 instruction set is largely designed around machine instructions that let you specify one register and one memory operand, because that is pretty useful, and it doesn't affect performance of operations that fetch to register and then put to memory in separate steps.

As with all complicated instruction set architectures, there are principles (e.g., the above) and then there are exceptions to the rule that serve some other purpose.

You might be interested in the MOVB/MOVW/MOVD instruction(s), which are in effect (respectively):

 MOV byte[edi], byte[esi]; add edi,1; add esi,1
 MOV word[edi], word[esi]; add edi,2; add esi,2
 MOV dword[edi], dword[esi]; add edi,4, add esi,4

(No, you don't get to choose the registers; these are hardwired to use ESI and EDI). By itself this isn't very interesting (other than doing exactly what you want :), but it can be repeated using an REP prefix to consttruction a block move. And the chip designers work very hard to make this kind of block move run extremely fast.

[For 64 bit x86, there's a MOVQ that operates on qwords].

If you are going to write assembly code, it is well worth your trouble to read the instruction set description carefully before you write much code.

Ira Baxter
  • 93,541
  • 22
  • 172
  • 341
0

The acceptable operands for the mov instruction are shown here.

mov [eax], [ebx] is attempting to move one memory location (dereferenced from the value in the ebx register) to the memory location referred to in eax. There is no opcode for mov that takes a memory location as both the source and the destination, but there are opcodes for moving a memory location into a register, a register into a memory location, an immediate to a register, an immediate to a memory location, or a 16-bit GPR into a segment register.

Govind Parmar
  • 20,656
  • 7
  • 53
  • 85