【问题标题】:What is the 0x10 in the "leal 0x10(%ebx), %eax" x86 assembly instruction?“leal 0x10(%ebx), %eax” x86 汇编指令中的 0x10 是什么?
【发布时间】:2011-04-29 13:37:47
【问题描述】:

对于这条 LEAL 指令,0x10 的功能是什么?是乘法还是加法还是别的什么?

leal 0x10(%ebx), %eax

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

【问题讨论】:

    标签: assembly x86 instructions


    【解决方案1】:

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

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

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

    【讨论】:

      【解决方案2】:

      leal 或 lea 全名是“加载有效地址”,它就是这样做的:它进行地址计算。

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

      eax = ebx + 0x10

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

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

      【讨论】:

      • 对编译器的解释非常好..真的
      • 此外,如前所述,leal 可用于进行算术运算。但它不设置控制代码。因此,不应用于有条件的跳跃或有条件的移动。
      【解决方案3】:

      要添加到 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

      希望对你有帮助

      【讨论】:

        【解决方案4】:

        GNU 2.18 文档

        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 当你看到它时,就会清楚为什么地址的某些部分可能会被省略,以及每个表单将编译成什么。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-06-01
          • 1970-01-01
          • 2020-03-10
          • 1970-01-01
          • 2011-02-02
          • 1970-01-01
          • 2010-10-16
          • 1970-01-01
          相关资源
          最近更新 更多