29

我对组装很陌生,并且有一些非常基本的问题。

这四个命令有什么区别?

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

他们说括号的意思是“获取地址的值”。但是,那么,第一行真的有什么作用呢?它不会将eax的值移动到ebx中吗?如果是这样,那么括号的意义是什么?

4

2 回答 2

58

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

mov ebx, eax

只需将值复制eaxebx寄存器中

 | EAX : 0123456 |   ---->   | EAX : 0123456 |
 | EBX : 0000000 |   ====>   | EBX : 0123456 |

现在让我们添加一些内存空间

ADDRESS         VALUE
000000          6543210
000004          5189784
000008          1698791
00000C          9816517
000010          9816875
000014          5498156

mov [ebx], eax

将值eax移入ebx.

 | EAX : 0123456 |   --no-->   | EAX : 0123456 |
 | EBX : 0000008 | --change--> | EBX : 0000008 |

ADDRESS         VALUE           VALUE
000000          6543210   ----> 6543210   
000004          5189784   ----> 5189784   
000008          1698791   ====> 0123456
00000C          9816517   ----> 9816517   
000010          9816875   ----> 9816875   
000014          5498156   ----> 5498156   

mov ebx, [eax]

将值从包含的内存地址移动eaxebx

 | EAX : 0000008 |   ---->   | EAX : 0000008 |
 | EBX : 0123456 |   ====>   | EBX : 1698791 |

ADDRESS         VALUE    
000000          6543210    
000004          5189784  
000008          1698791  
00000C          9816517   
000010          9816875    
000014          5498156    

mov [ebx], [eax]

最后,您会认为会将值从包含的内存地址移动到包含eax的内存地址ebx

 | EAX : 0000008 |   --no-->   | EAX : 0000008 |
 | EBX : 000000c | --change--> | EBX : 000000c |

ADDRESS         VALUE           VALUE
000000          6543210   ----> 6543210   
000004          5189784   ----> 5189784   
000008          1698791   ----> 1698791   
00000C          9816517   ====> 1698791   
000010          9816875   ----> 9816875   
000014          5498156   ----> 5498156 

但是 x86 架构不允许这种组合。 你不能从一个记忆移到另一个记忆

因此,括号的使用等同于取消引用操作。

于 2018-02-04T13:29:47.190 回答
4

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

在 x86 汇编中,一些寄存器可以用作数据寄存器地址寄存器(与其他体系结构不同)。这些寄存器称为 GPR(“通用寄存器”)。它们可以包含 32 位值32 位地址。他们的“名字”是EAX, EBX, ECX, EDX, ESI, EDI, ESP, EBP.

mov ebx, eax

确实将值移动EAXEBX.

mov [ebx], eax

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

mov ebx, [eax]

EAX确实将 32 位地址指向的 32 位 DWORD 值移入EBX

mov [ebx], [eax]

是 32 位 Intel 汇编中的无效指令,因为基本的 x86 汇编不支持一个(两个操作数)指令中的两个内存操作数。具有三个或四个操作数的较新指令(SSE、AVX)能够使用多个内存操作数。这是更复杂的指令编码(使用指令前缀)的结果。

于 2018-02-04T13:23:33.663 回答