Assembly 为什么不能执行mov[eax],[ebx]

Assembly 为什么不能执行mov[eax],[ebx],assembly,x86,Assembly,X86,我可以这样做: mov eax, ebx 这是: mov [eax], ebx 即使这样: mov eax, [ebx] 但不是这个(错误C2415): mov [eax], [ebx] 只是wtf。。。为什么? 它与*ptr1=*ptr2相同,为什么我能够将一个寄存器复制到另一个寄存器,通过寄存器中的addres将值复制到另一个寄存器,或者将寄存器的值复制到另一个寄存器中存储的地址 但它不能将一个地址上的值复制到另一个地址。为什么?显示了mov指令可接受的操作数 mov[eax],[e

我可以这样做:

mov eax, ebx
这是:

mov [eax], ebx
即使这样:

mov eax, [ebx]
但不是这个(错误C2415):

mov [eax], [ebx]
只是wtf。。。为什么? 它与*ptr1=*ptr2相同,为什么我能够将一个寄存器复制到另一个寄存器,通过寄存器中的addres将值复制到另一个寄存器,或者将寄存器的值复制到另一个寄存器中存储的地址


但它不能将一个地址上的值复制到另一个地址。为什么?

显示了
mov
指令可接受的操作数


mov[eax],[ebx]
正试图将一个内存位置(从
ebx
寄存器中的值解除引用)移动到
eax
中引用的内存位置。没有将内存位置作为源和目标的mov操作码,但有将内存位置移动到寄存器、寄存器移动到内存位置、寄存器立即数、内存位置立即数或段寄存器16位GPR的操作码。

mov[eax]、[ebx]
意味着“将
ebx
指向的内存位置的内容移动到
eax
指向的内存位置。这是一种内存到内存的移动,Intel不支持。

您不能执行mov[eax],[ebx]因为这意味着一条机器指令将允许您指定两个内存操作数。x86指令集主要是围绕允许您指定一个寄存器和一个内存操作数的机器指令设计的,因为这非常有用,并且不会影响提取到寄存器然后放入内存的操作的性能分步进行

与所有复杂的指令集体系结构一样,有一些原则(如上述原则),也有一些规则的例外,用于其他目的

您可能对MOVB/MOVW/MOVD指令感兴趣,这些指令(分别)有效:

(不,你不需要选择寄存器;这些寄存器是硬连线的,可以使用ESI和EDI)。这本身并不有趣(除了做你想做的以外:),但可以使用REP前缀重复构建块移动。芯片设计者非常努力地使这种块移动运行得非常快

[对于64位x86,有一个在qwords上运行的MOVQ]


如果您要编写汇编代码,在编写大量代码之前仔细阅读指令集说明是值得的。

x86处理器不支持
mov
的两个内存操作数。请参阅指令集参考和/或基本体系结构手册。要实现所需功能,您需要仔细阅读一个寄存器。由于CPU不支持它,这是
*ptr1=*ptr2
编译成的:另一个副本:。请参阅也不要将汇编作为“编程语言”,它更像是“CPU指令的名称”,即CPU供应商在硬件中实现的内容,在汇编程序中作为指令提供。也有一些例外,比如有一些帮助宏或“伪指令”(一个伪ins.被转换成多个本机指令),但通常映射是1:1,即源代码文本中的一条指令映射到CPU识别的一条HW指令。如果CPU供应商不提供
mov[eax],[ebx]
,则汇编程序对此无能为力(至少它会报告错误,有些则不会)。请注意,虽然不支持常规内存到内存的移动,但支持一些特殊情况(如
推送m32
)。
 MOV byte[edi], byte[esi]; add edi,1; add esi,1
 MOV word[edi], word[esi]; add edi,2; add esi,2
 MOV dword[edi], dword[esi]; add edi,4, add esi,4