【问题标题】:What is the significance of the LEA instruction "=> 0xb48daed9 <+3479>: lea -0xc(%ebp),%esp"?LEA指令“=> 0xb48daed9 <+3479>: lea -0xc(%ebp),%esp”的意义是什么?
【发布时间】:2015-03-12 09:15:45
【问题描述】:

谁能告诉我这个汇编指令的意义是什么:

0xb48daed9 &lt;+3479&gt;: lea -0xc(%ebp),%esp

我对组装说明不太满意。实际上,我在我的应用程序中得到了一个 SIGABRT,而罪魁祸首似乎是这条特殊的汇编指令。

【问题讨论】:

标签: c++ c assembly


【解决方案1】:

在机械层面上,指令

lea -0xc(%ebp),%esp

-0xc(即:-12)添加到%ebp,并将结果写入%esp

在逻辑层面,它分配被调用函数的栈帧。我希望在与此类似的上下文中看到它:

push %ebp            ; save previous base pointer
mov %esp,%ebp        ; set %ebp = %esp: old stack pointer is new base pointer
lea -0xc(%ebp),%esp  ; allocate 12 bytes for local variables

%ebp%esp 是堆栈指针寄存器。 %ebp 指向堆栈帧的底部,%esp 指向它的“顶部”(实际上是底部,因为堆栈向下增长),因此 lea 指令将堆栈指针移动到底部下方 12 个字节,从而获得声明局部变量的 12 个字节。在保存旧基指针并将新基指针设置为旧堆栈指针后执行此操作会将 12 字节的新帧推入调用堆栈。

这条指令本身似乎不太可能导致陷阱,但在堆栈溢出的情况下,分配的堆栈帧将无效,并且在尝试使用它时会发生爆炸。我怀疑你有一个失控的递归函数。

正如@abligh 提到的,另一种可能性是堆栈指针在沿线某处损坏。如果在堆栈分配的缓冲区中发生缓冲区溢出,从而导致先前保存的基指针被垃圾覆盖,则可能会发生这种情况。从函数返回后,垃圾会被恢复以代替被覆盖的基指针,随后的函数调用将没有任何可处理的东西。

【讨论】:

    【解决方案2】:

    lea -0xc(%ebp),%esp 将:

    • 计算%ebp - 12的有效地址[1],并
    • 存储在%esp

    它已经/被用于对内存操作数执行快速算术运算。根据 Intel 手册,如果源操作数不是内存位置,它可能会抛出异常。

    [1]“有效地址”,用 Intel 的说法,是一个偏移量,可以作为静态值或以下形式的地址计算提供:Offset = Base + (Index * Scale) + Displacement

    【讨论】:

    • 您应该解释“如果源(在您的情况下为 ebp 寄存器)不是内存位置,它可能会引发异常”的意思。 ebp 不是内存位置。如果它是一个内存位置,它就必须是一个有效的内存位置,我只能假设您误解了说明这一点的文档,但精确的参考可以消除任何歧义。
    • 您还应该解释一下,当您说“计算有效地址”时,您真正的意思只是“计算”:指令集%esp 等于%ebp-12。 (但我不知道它会抛出异常。)
    • @PascalCuoq,谢谢,我写的显然是错误的。 TonyK:我是按照英特尔在手册中对“有效地址”的定义进行的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-04
    • 1970-01-01
    • 2011-02-11
    • 1970-01-01
    • 2012-02-27
    • 1970-01-01
    相关资源
    最近更新 更多