我可以这样做:
mov eax, ebx
这:
mov [eax], ebx
甚至是这个:
mov eax, [ebx]
但不是这个(错误C2415):
mov [eax], [ebx]
只是wtf ...为什么? 它与* ptr1 = * ptr2一样,为什么我可以将一个寄存器复制到另一个寄存器,为什么要通过寄存器中的地址将值复制到另一个寄存器中,或者将寄存器的值复制到另一个寄存器中存储的地址...
但是它不能将一个地址的值复制到另一个地址。为什么?
答案 0 :(得分:1)
mov [eax], [ebx]
的意思是“将ebx
指向的存储位置的内容移动到指向eax
的存储位置。这就是内存到内存的移动,英特尔不支持。
答案 1 :(得分:0)
mov
指令可接受的操作数显示为here。
mov [eax], [ebx]
试图将一个存储位置(从ebx
寄存器中的值取消引用)移动到eax
所引用的存储位置。没有mov
的操作码将存储位置同时作为源和目的地,但是有用于将存储位置移动到寄存器,将寄存器移动到存储位置,紧靠寄存器,即时的存储器位置,或一个16位GPR入段寄存器。
答案 2 :(得分:0)
您不能执行mov [eax],[ebx],因为这意味着机器指令将允许您指定两个内存操作数。 x86指令集主要是围绕机器指令设计的,这些指令使您可以指定一个寄存器和一个内存操作数,因为这非常有用,并且它不会影响取回寄存器然后分别放入内存的操作的性能。 / p>
与所有复杂的指令集体系结构一样,有一些原则(例如,上面的原则),然后该规则的例外也有其他用途。
您可能对分别生效的MOVB / MOVW / MOVD指令感兴趣:
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
(不,您不必选择寄存器;这些寄存器硬性使用ESI和EDI)。就其本身而言,这不是很有趣(除了完全按照您的意愿进行:),但是可以使用REP前缀重复此操作以构造块移动。而且,芯片设计人员非常努力地使这种块移动运行得非常快。
[对于64位x86,有一个在qword上运行的MOVQ]。
如果要编写汇编代码,那么在编写大量代码之前仔细阅读指令集描述是很值得的。