On the mechanical level, the instruction
lea -0xc(%ebp),%esp
adds -0xc
(that is: -12) to %ebp
and writes the result to %esp
.
On the logical level, it allocates a called function's stack frame. I'd expect to see it in a context similar to this:
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
and %esp
are the stack pointer registers. %ebp
points to the base of the stack frame and %esp
to its "top" (actually the bottom because the stack grows downward), so the lea
instruction moves the stack pointer 12 bytes below the base, staking a claim of 12 bytes for local variables. Doing this after saving the old base pointer and setting the new base pointer to the old stack pointer pushes a new frame of 12 bytes onto the call stack.
It seems unlikely that this instruction itself causes a trap, but in the event of a stack overflow, the allocated stack frame will be invalid and explosions are expected when trying to use it. My suspicion is that you have a runaway recursive function.
Another possibility, as @abligh mentions, is that the stack pointer became corrupted somewhere along the line. This can happen, among other things, if a buffer overflow happens in a stack-allocated buffer so that a previously saved base pointer is overwritten with garbage. Upon return from the function, the garbage is restored in lieu of the overwritten base pointer, and a subsequent function call will not have anything sensible with which to work.