LEA 指令“=> 0xb48daed9 <+3479>: lea -0xc(%ebp),%esp”有什么意义?

What is the significance of the LEA instruction "=> 0xb48daed9 <+3479>: lea -0xc(%ebp),%esp"?

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

0xb48daed9 <+3479>: lea -0xc(%ebp),%esp

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

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

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

它有 been/is 用于使用内存操作数执行快速算术运算。根据英特尔手册,如果源操作数不是内存位置,它可能会抛出异常。

[1] "Effective address",按照英特尔的说法,是一个偏移量,它作为静态值或以下形式的地址计算提供:Offset = Base + (Index * Scale) + Displacement

在机械层面,指令

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 指向它的 "top" (实际上是底部,因为栈向下增长),所以 lea 指令移动栈指针 12基数以下的字节,为局部变量声明 12 个字节。在保存旧基指针并将新基指针设置为旧堆栈指针后执行此操作会将一个 12 字节的新帧推入调用堆栈。

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

如@abligh 所述,另一种可能性是堆栈指针在该行的某处损坏。如果在堆栈分配的缓冲区中发生缓冲区溢出,从而导致先前保存的基指针被垃圾覆盖,则可能会发生这种情况。从函数 return 开始,垃圾被恢复以代替被覆盖的基指针,随后的函数调用将没有任何有意义的工作。