为什么一条指令在汇编中不能包含两个内存引用?

时间:2013-07-07 17:36:46

标签: assembly x86

我是汇编语言的初学者。我已经了解到以下指令无效,因为它不能同时具有源和目标作为内存引用。我想知道原因。

movl (%eax) (%ebx)  

3 个答案:

答案 0 :(得分:7)

指令集要求设计位模式以对指令进行编码。对于每个可以想到的指令,可以有位模式,但是处理器构造起来是不实际的。因此,处理器设计人员限制了指令的多样性(通常也就是风格),使处理器构造更容易。

处理器设计的一个共同主题是指令在一个寄存器和一个内存位置上运行。两个操作数意味着这种风格可以加载内存来注册,将寄存器存储到内存,以及各种常见的二进制操作,例如添加内存来注册,比较寄存器到内存等。这个主题在实践中运行良好,几乎不需要对于在多个内存位置上工作的指令,它的规律性使得CPU的“中央”处理部分更容易实现。你提到的“movl”指令符合这个主题,因此只有一个内存操作数。

所以真正的答案是,拥有这样一条指令的回报并不能证明工程的合理性。

大多数处理器设计已经存在了20多年,现在晶体管相对便宜。因此,几乎所有这些机器的指令集都变得更加复杂,通常包括引用多个存储器操作数的一些指令。但这些说明是例外,而不是规则。

答案 1 :(得分:3)

没有真正的原因 - 这就是英特尔指令集恰好被定义的方式。

答案 2 :(得分:0)

某些指令需要很快,他们无法一直访问所有输入端口。首先必须先将一个数据输入寄存器,因为cpu是这样做的。然后通过另一个端口,将数据发送到另一个地址。

要获得更多的流水线深度,某些指令甚至无法为源和目标使用相同的寄存器。对源和目标使用相同类型的寄存器或相同的寄存器或存储器会使流水线更难。

示例:处理器可以在执行C ----> D时从A ---> B寄存器进行复制。但不能同时做A -----> A和A ----- B.即使只是读取寄存器,也很难在下一条指令中访问它。所以最有效的是在源和目的地使用不同的东西。

对源和目标使用内存使得该指令高度依赖于有关内存和端口的事情,这是低效的。只有高度优化的指令才能做到这一点。

更难的流水线操作会使关键部件变慢。

正如艾拉·巴克斯特所说,将所有寄存器连接到所有其他寄存器(并对存储器输入端口做同样的事情),会使cpu变得更大,更难生成。