Reputation: 15387
I'm disassembling some x86 assembly code compiled with GCC for an assignment.
Immediately before calling a function, I have:
$esp = 0xffffdbd0
Setting a breakpoint on the very first line of the function called (even before the push
) gives:
$esp = 0xffffdbcc
After the push:
$esp = 0xffffdbc8
So why is $esp
changing like that? Theoretically, just going to a function shouldn't change the stack pointer, and then it changes after the push
? What's going on?
I have a guess, that it has to do with alignment, and that somehow some sort of alignment is going on behind my back with the call
and push
assembly instructions. But that's a guess; I have no idea.
Can someone who knows clarify?
Upvotes: 0
Views: 982
Reputation: 30449
Your assumption
Theoretically, just going to a function shouldn't change the stack pointer
is plain wrong. Going to a function does exactly that: It changes the stack pointer, notably it pushes the return address on it. "Pushing" in x86 (and in almost every other arch) always means implicitly decrementing the stack pointer and storing the value to be pushed on it.
Upvotes: 2
Reputation: 18522
When you execute a CALL
instruction, the address of the instruction immediately after the CALL
is pushed onto the stack. This is so that when you execute a RET
instruction, the program can jump back to the right address and continue executing instructions. Pushing this address onto the stack means that you can have nested CALL
s and have no problems returning to the correct address at each RET
.
Since this is a 32-bit system, 4 bytes will be pushed onto the stack:
0xffffdbd0 - 0xffffdbcc = 0x4
Upvotes: 4
Reputation:
The call
instruction pushes the address of the first instruction after itself to the stack before jumping to the target location. This way, ret
knows where to go after the function returns.
Upvotes: 3