我对组装很陌生,并且有一些非常基本的问题。
这四个命令有什么区别?
mov ebx, eax
mov [ebx], eax
mov ebx, [eax]
mov [ebx], [eax]
他们说括号的意思是“获取地址的值”。但是,那么,第一行真的有什么作用呢?它不会将eax的值移动到ebx中吗?如果是这样,那么括号的意义是什么?
我对组装很陌生,并且有一些非常基本的问题。
这四个命令有什么区别?
mov ebx, eax
mov [ebx], eax
mov ebx, [eax]
mov [ebx], [eax]
他们说括号的意思是“获取地址的值”。但是,那么,第一行真的有什么作用呢?它不会将eax的值移动到ebx中吗?如果是这样,那么括号的意义是什么?
让我们做一个非常简单的例子,假设我们有一个只有两个寄存器 EAX 和 EBX 的 CPU。
mov ebx, eax
只需将值复制eax
到ebx
寄存器中
| 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]
将值从包含的内存地址移动eax
到ebx
。
| 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 架构不允许这种组合。 你不能从一个记忆移到另一个记忆。
因此,括号的使用等同于取消引用操作。
您在说明中缺少操作数分隔符,
。我不知道(还)没有它的任何汇编程序。我在引号中修复了它。
在 x86 汇编中,一些寄存器可以用作数据寄存器或地址寄存器(与其他体系结构不同)。这些寄存器称为 GPR(“通用寄存器”)。它们可以包含 32 位值或32 位地址。他们的“名字”是EAX
, EBX
, ECX
, EDX
, ESI
, EDI
, ESP
, EBP
.
mov ebx, eax
确实将值移动EAX
到EBX
.
mov [ebx], eax
确实将值移动EAX
到 32 位地址指向的 32 位 DWORD 值EBX
mov ebx, [eax]
EAX
确实将 32 位地址指向的 32 位 DWORD 值移入EBX
mov [ebx], [eax]
是 32 位 Intel 汇编中的无效指令,因为基本的 x86 汇编不支持一个(两个操作数)指令中的两个内存操作数。具有三个或四个操作数的较新指令(SSE、AVX)能够使用多个内存操作数。这是更复杂的指令编码(使用指令前缀)的结果。