Assembler Function Calls

Registers
instruction pointer top of stack pointer base pointer

C Calling Convention
How are functions called in C?

The callee function should have its own, thus, to restore the state after the function call, the caller's   must be saved on the stack.

Caller: pushl 2(%eip) # save return address (next instruction) jmp function
 * push all function parameters onto stack (in reverse order)
 * issue  - equivalent to:

Callee: movl %ebp, %esp # copy base pointer to stack pointer again like before the call # - this has the effect of de-allocating all local variables popl %ebp      # restore old base pointer from stack popl %eip
 * save  containing the base pointer of the caller to the stack
 * copy stack pointer to  - now we can reference the parameters and return address relatively to
 * reserve space for local variables by moving stack pointer up (e.g.  reserves space for 2 words)
 * perform computations using parameters (positive offsets to ) and local variables (negative offsets to  )
 * store return value in
 * restore caller stack frame - equivalent to:
 * return to caller - equivalent to:

In Code
pushl $10       # push argument 1 to stack pushl $20       # push argument 2 to stack pushl 2(%eip)   # save return address (next instruction) jmp function ... function: pushl %ebp      # save caller base pointer movl %esp, %ebp # define callee base pointer subl $4, %esp   # allocate space for local variables # (1 word, in this example) ...    movl %ebp, %esp  # de-allocate local variables popl %ebp       # restore caller base pointer from stack popl %eip       # ret

Or the short version: pushl $10       # push argument 1 to stack pushl $20       # push argument 2 to stack call function function: enter 4 ...    leave ret

gcc Example
A simple function call: int addNumbers(int x, int y) { int z = x+y; return z;                 } int main(void) { return addNumbers(30, 50); }                            Compiles to: ... addNumbers: pushl  %ebp            # save caller base pointer movl   %esp, %ebp      # use current stack pointer as base pointer # for addNumbers subl   $4, %esp        # reserve one word for z         movl    12(%ebp), %eax  # copy y to %eax (50) addl   8(%ebp), %eax   # add x to %eax (50+30=80) movl   %eax, -4(%ebp)  # copy %eax to z         movl    -4(%ebp), %eax  # copy z to %eax (redundant, z didn't need to                                 #                 be introduced at all, but                                 #                 who cares :) leave                  # restore caller stack frame ret                    # return to caller ... main: ...        subl    $8, %esp        # reserve space in stack for 2 arguments movl   $50, 4(%esp)    # push 50 to one below top of stack (y) movl   $30, (%esp)     # push 30 to top of stack (x) call   addNumbers      # call function ... memory layout after z               %ebp - 4 = %esp old base pointer %ebp return address  %ebp + 4 x               %ebp + 8 y               %ebp + 12