The Code
The following simple x86 assembly code is listed on Wikibooks for the CDECL calling convention:
Function Definition:
_MyFunction1:
push ebp
mov ebp, esp
mov eax, [ebp + 8]
mov edx, [ebp + 12]
add eax, edx
pop ebp
ret
Calling Function:
push 3
push 2
call _MyFunction1
add esp, 8
It is what would be generated from the following C code:
_cdecl int MyFunction1(int a, int b)
{
return a + b;
}
And this function call:
x = MyFunction1(2, 3);
The issue
Unfortunately, I can't fully wrap my head around what is happening here. Here's a list of the events as I understand them, starting from the calling function:
- push integer 3 onto the stack
- push integer 2 onto the stack
- call _MyFunction1, pushing Instruction Pointer IP onto the stack
- push base pointer ebp onto the stack, as to be able to restore it later. I suppose this is only necessary because we are moving a value into ebp in the next instruction?
- move value of current stack pointer esp into ebp for later use in memory adressing. Why do this? Why not just use the value of esp in the next two instructions directly (i.e. [esp + 8], [esp + 12])
- get the two integer values we pushed onto the stack and save them in eax and edx. Obviously, we do this by pointing to a memory address each. How does the processor know how "far" it has to look until it fully read e.g. the integer 3? How does it know that it's a 32 or a 16 bit integer here? How exactly do the 8 and the 12 as the stack pointer offset come to be? What do they mean, e.g. does 8 mean an 8bit offset?
- add the two values together into eax
- restore ebp from the stack
- return, i.e. popping eip containing the next instruction from the stack and jumping to it
- add 8 (again, what unit?) to the stack pointer esp
- now, with CDECL, the caller has to clean up the stack. I reckon this is supposed to have happened with this instruction. But how is simply advancing the pointer a way of cleaning the stack up? The 3 and 2 integer values have never been popped. If anything, I'd have thought decreasing the pointer value would do the trick, and not increasing it as done here