Search code examples
assemblymemoryx86intel-syntax

What do square brackets mean in x86 assembly?


I'm very new to assembly, and have some very basic questions.

What is the difference between these four commands?

mov ebx, eax
mov [ebx], eax
mov ebx, [eax]
mov [ebx], [eax]

They say that the brackets mean "get the value of the address". But what, then, does that very first line really do? Does it not move the value of eax into ebx? If it does, then what are the point of the brackets?


Solution

  • 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.