0
votes

I am new to Assembly and reading about calling convention in x86 .

In one of the example below .

cdecl int MyFunction1(int a, int b)
{
 return a + b;
}


 x = MyFunction1(2, 3);


_MyFunction1:
push ebp
mov ebp, esp
mov eax, [ebp + 8]
mov edx, [ebp + 12]
add eax, edx
pop ebp
ret

push 3
push 2
call _MyFunction1
add esp, 8

I am able to understand most part of the given code but have doubt on one line where pop ebp has been done.

I think right call will be "pop [ebp+4]" because after push ebp , mov ebp ,esp is performed which cause ebp pointer to decremented by 4 and hence to reach to original position have to add 4 bytes to ebp.

2
xen-0 answer is correct, but you don't even need e full prologue/epilogue (you are not using stack instructions in your body, so no need to restore esp wit a mov) In general, you usually need the mov only if you are making space for locals with a sub in the prologue - Lorenzo Dematté

2 Answers

3
votes

The typical epilogue reads:

mov esp, ebp
pop ebp
ret

The old ebp is stored at the address your current ebp is pointing to. Hence mov esp, ebp puts the stack pointer at this address, so pop ebp will restore ebp correctly (and esp).

It so happens that you can forgo the mov esp, ebp instruction in your function, since you never use the stack and ebp and esp already point to the same address.

pop [ebp+4] would be incorrect, since that would put the value at the top of the stack into [ebp+4]

0
votes
push ebp
la la la la la la la la la la 
pop ebp
ret

So it's fine.

One push

One pop