Let's make a very simple example and imagine we have a CPU with only two registers, EAX and EBX.
mov ebx, eax
Simply copies the value in eax
to the ebx
register
| EAX : 01234567 | ----> | EAX : 01234567 |
| EBX : 00000000 | ====> | EBX : 01234567 |
Now let's add some memory space
ADDRESS VALUE
00000000 6A43210D
00000004 51C9A847
00000008 169B87F1
0000000C C981A517
00000010 9A16D875
00000014 54C9815F
mov [ebx], eax
Moves the value in eax
to the memory address contained in ebx
.
| EAX : 01234567 | --no--> | EAX : 01234567 |
| EBX : 00000008 | --change--> | EBX : 00000008 |
ADDRESS VALUE
00000000 6A43210D -> 6A43210D
00000004 51C9A847 -> 51C9A847
00000008 169B87F1 =====> 01234567
0000000C C981A517 -> C981A517
00000010 9A16D875 -> 9A16D875
00000014 54C9815F -> 54C9815F
mov ebx, [eax]
Moves the value from the memory address contained in eax
to ebx
.
| EAX : 00000008 | -> | EAX : 00000008 |
| EBX : 01234567 | ====> | EBX : 169B87F1 |
[No change to memory]
ADDRESS VALUE
00000000 6A43210D
00000004 51C9A847
00000008 169B87F1
0000000C C981A517
00000010 9A16D875
00000014 54C9815F
mov [ebx], [eax]
This, finally, you would think would move the value from the memory address contained in eax
to the memory address contained in ebx
.
| EAX : 00000010 | --no--> | EAX : 00000010 |
| EBX : 00000008 | --change--> | EBX : 00000008 |
ADDRESS VALUE
00000000 6A43210D -> 6A43210D
00000004 51C9A847 -> 51C9A847
00000008 169B87F1 =====> 9A16D875
0000000C C981A517 -> C981A517
00000010 *9A16D875 -> 9A16D875
00000014 54C9815F -> 54C9815F
But this combination is disallowed by the x86 architecture. You cannot move from memory to memory.
The use of brackets is therefore equivalent to a dereferencing operation.
*
operator in C. Also, the last one is invalid. – Statued[ebx],[eax]
, ebx and eax contain addresses, i.e. both are referencing memory. and you can't copy from memory to memory directly: the processor doesn't have instructions for that. – Schultemovs
,push [mem]
andpop [mem]
all copy memory to memory, with one or both operands being implicit. x86 instructions have at most one modrm + optional displacement explicit addressing mode. That's whymov
doesn't work but other instructions do. – Handspring[]
, check here: #58960465 – Infinitesimal