“leal 0x10(%ebx),%eax”x86汇编指令中的0x10是多少?

时间:2010-10-23 12:11:38

标签: assembly x86 instructions

关于这个LEAL指令,0x10的功能是什么?它是一个乘法或加法还是其他东西?

leal 0x10(%ebx), %eax

有人可以澄清一下吗?这是Linux机器上的x86汇编程序。

4 个答案:

答案 0 :(得分:71)

leal,或者lea全名是“加载有效地址”,它的确如此:它进行地址计算。

在您的示例中,地址计算非常简单,因为它只是向ebx添加了一个偏移量并将结果存储在eax中:

eax = ebx + 0x10

lea可以做更多事情。它可以添加寄存器,将寄存器与常数2,4和8相乘,用于字,整数和双精度的地址计算。它还可以添加偏移量。

请注意,lea的特殊之处在于它永远不会修改标志,即使您将其用作上述示例中的简单添加项。编译器有时会利用此功能并用lea替换添加以帮助调度程序。由于这个原因,看到lea指令在编译代码中进行简单算术并不罕见。

答案 1 :(得分:4)

lea代表“加载有效地址”;这是一种使用IA32指令集的复杂地址模式进行算术运算的方法。 l后缀是一种区分GNU语法中指令操作数大小的方法,就像你在Linux机器上一样。

所以,简而言之,是的,这是一种加法指令。它还可以同时处理乘法2,4或8。

另请参阅this related question(他们使用英特尔语法讨论相同的指令):

答案 2 :(得分:2)

GNU as 2.18 docs

https://sourceware.org/binutils/docs-2.18/as/i386_002dMemory.html

  

AT& T:-4(%ebp),英特尔:[ebp - 4]

然后英特尔语法不言自明。

更重要的是,文档还解释了一般情况:

  

表格

的英特尔语法间接内存引用
 section:[base + index*scale + disp]
  

被翻译成AT& T语法

 section:disp(base, index, scale)
  

其中base和index是可选的32位基数和索引寄存器,disp是可选的位移,而scale,取值1,2,4和8,乘以index来计算操作数的地址

当我们省略地址的某些部分时,AT& T中的事情会变得有些混乱,例如: -4(%ebp),但通过文档中的示例,我们可以轻松推断出所有语法案例。

为了真正了解正在发生的事情,我建议您查看指令的编码方式。这是一个很好的教程:http://www.c-jump.com/CIS77/CPU/x86/lecture.html当你看到它时,会清楚为什么地址的某些部分可能会被省略,以及每个表格将编译成什么。

答案 3 :(得分:0)

要添加到Nils响应,

作为复习,IA32汇编程序中的地址模式通常采用以下形式:

IO(Rb,Ri,s),其中:

IO =立即偏移

Rb =基本寄存器

Ri =指数寄存器

s =缩放因子{1,2,4,8}

因此有效地址计算为 * IO + [Eb] + [Ei] s

leal 看起来与其他指令类似,比如movl,但它有点特别。 它不是从源读取到目的地,而是复制有效的 目的地来源的地址。

因此它可以用于为以后的内存引用生成指针,以及 正如Nils指出的那样,用于基本算术运算。

例如:

让寄存器%edx包含值x

leal 1(%edx,%edx,8),%eax

将加载1 + x + 8 * x = 1 + 9x的有效地址以注册%eax。

本质上,操作:

leal 来源目的地 => 目的地 = 地址 来源

如果您熟悉C,则相当于:

char * b =& a;

其中char a的地址分配给char指针b

更多例子:

让寄存器%eax保持值x,并注册%ecx保持值y

leal (%eax,%ecx,4),%edx会将值x + 4y分配给注册%edx

leal 0xB(,%ecx,5),%edx会将值0xB + 5y = 11 + 5y分配给%edx

leal (%eax,%eax,2),%eax会将值3x分配给寄存器%eax

希望这有帮助