Mauerer app03.tex V1 - 09/04/2008 6:11pm Page 1182
Appendix C: Notes on C
A procedure call therefore consists of the following two steps:
- Build a parameter list in the stack. Thefirstargument to be passed to the called function is
placedlaston the stack; this makes it possible to pass a varying number of arguments that
can bepoppedfrom the stack one after the other.
- Invokecall, which causes the current value of the instruction pointer (pointing to the
instruction thatfollowscall) to be pushed onto the stack and delegates code flow to the
invoked function.
The procedure called is responsible for managing the frame pointer and performs the following steps:
- The previous frame pointer is pushed onto the stack, thus moving the stack pointer down.
- The frame pointer is assigned the current value of the stack pointer and now marks the start
of the stack area for the function to be executed.
- The code of the function is executed.
- When the function terminates, the stored frame pointer is at the bottom of the stack. Its value
ispoppedfrom the stack and saved in the frame pointer that now again points to the start of
the stack area of the previous function. Thereturn address saved when the function was
called is now located at the bottom end of the stack.
- Invokingreturncauses the return address to bepoppedfrom the stack. The pro-
cessor branches to the return address, thus returning the code flow to the calling
function.
At first glance, this approach may seem a little confusing. To dispel any confusion, let’s consider the
following simple C example:
#include<stdio.h>
int add (int a, int b) {
return a+b;
}
int main() {
int a,b;
a=3;
b=4;
int ret = add(a,b);
printf("Result: %u\n", ret);
exit(0);
}
The following assembler code is generated on IA-32 systems — albeit with compiler optimization
switched off (which would produce much improved code but complicate the explanation). This example
uses Intel representation because it is easier to read and explain than the AT&T variant preferred by
the GCC. Line numbers are not usually included in assembler syntax, but they have been added here to
simplify the code explanation.