x86 汇编中的方括号是什么意思?

What do square brackets mean in x86 assembly?

我是汇编的新手,有一些非常基本的问题。

这四个命令有什么区别?

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

他们说括号的意思是"get the value of the address"。但是,那么,第一行到底有什么作用呢?它不会将 eax 的值移动到 ebx 中吗?如果是,那么括号的意义何在?

您在说明中缺少操作数分隔符 ,。我不知道(还)没有它的任何汇编器。我在引号中修复了它。

在 x86 汇编中,一些寄存器可以用作数据寄存器 作为地址寄存器(与其他架构的区别)。这些寄存器称为 GPR(“通用寄存器”)。它们可以包含 32 位值 32 位地址。他们的“名字”是EAXEBXECXEDXESIEDIESPEBP.

mov ebx, eax

确实将 EAX 中的值移动到 EBX

mov [ebx], eax

确实将EAX中的值移动到EBX

中的32位地址指向的32位DWORD值

mov ebx, [eax]

确实将EAX中的32位地址指向的32位DWORD值移动到EBX

mov [ebx], [eax]

是 32 位 Intel 汇编中的无效指令,因为 x86 机器代码不支持在一条指令中包含两个任意内存操作数,仅在至少一个内存操作数是隐式的特殊情况下才支持,例如 push dword [ebx][ebx] 读取内存并在 [esp - 4] 写入内存。参见

让我们做一个非常简单的例子,假设我们有一个 CPU 只有两个寄存器,EAX 和 EBX。

mov ebx, eax

简单地将eax中的值复制到ebx寄存器

 | EAX : 01234567 |   ---->   | EAX : 01234567 |
 | EBX : 00000000 |   ====>   | EBX : 01234567 |

现在让我们添加一些内存space

ADDRESS           VALUE
00000000          6A43210D
00000004          51C9A847
00000008          169B87F1
0000000C          C981A517
00000010          9A16D875
00000014          54C9815F

mov [ebx], eax

eax中的值移动到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]

将值从eax中包含的内存地址移动到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]

最后,您会认为会将值从 eax 中包含的内存地址移动到 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 

但是 x86 架构不允许这种组合。 You cannot move from memory to memory.

因此,括号的使用等同于 dereferencing 操作。