ADD指令或加号?

时间:2015-02-24 18:49:44

标签: assembly x86 masm

非常明智的问题,但我没有找到一个好的答案,所以我在这里问。
我看到有时为了添加我们使用ADD指令,有时我看到使用加号(+) 请看以下内容:

mov eax,[esi + TYPE DWORD]

嗯,我了解到为了添加数字,我应该使用ADD指令,但它似乎是这样工作的 我认为应该这样做:

add esi, TYPE DWORD
mov eax,[esi]
sub esi, TYPE DWORD

我的意思是,如何在不执行添加指令的情况下访问内存地址 esi + TYPE DWORD ?太奇怪了...

非常感谢你阅读(:

2 个答案:

答案 0 :(得分:3)

为了更加通用,你在第一个例子中看到的是寻址模式的一部分,而不是操作码。

最简单的地址寄存器只是指向你感兴趣的东西(基地址)

[bx]

如果您正在查看数组或结构,则必须调整基址寄存器以查看其他任何内容。时间继续前进,寻址变得更加灵活。你可以有一个基数和一个索引:

[ebx+eax]    ; add 2 registers to get the pointers - array + index

现在,如果你有一个字节数组,你可以保留基数并调整索引。如果您要查看2,4或8个字节,可以按目标大小调整索引:

[ebx+eax*2]   ; 2 byte target, array + (index*2)

现在,如果您正在查看c风格的结构,那么您也可以在结果地址中添加位移:

[ebx+eax*2+16]

这些在编译时被编码到指令中,而不是变成汇编指令。熟悉寻址模式 - 如果您使用正确的模式获得正确的解决方案,它们将为您节省大量时间。

答案 1 :(得分:2)

首先,这些被编码为两个不同的东西 - ADD是一个指令,将带有完整的操作码,而+将由汇编程序转换为参考模式它附加的主要指令(在这种情况下为MOV)。

然而,主要区别在于第一个将由存储器单元(或更准确地说 - 地址生成单元)执行,而不会在加载执行之上消耗任何额外的仲裁,而后者将通过ALU执行并相应地消耗所需的资源(取决于微架构,但在您的示例中,在任何现代无序CPU上至少需要几个队列条目,解码插槽,调度插槽,端口等等。) 。

从这个意义上说,第一个通常是“更便宜”,这就是为什么它经常被用于没有内存引用的正常算术运算,通过使用LEA指令,正如Harold指出的那样。