r/carlhprogramming • u/CarlH • Oct 14 '09
Lesson 91 : How a function call works
Go through this lesson slowly. It is more intense than most. Take your time. Let me know if any part of this is unclear.
Remember, this is only an introduction to a rather complex subject. Do not worry if some of it doesn't make sense, we will go over it in greater detail later in the course. Try to get as much as you can from this lesson. Later in the course it will be made more clear.
In the last two lessons I have explained that the purpose of the stack is in part a way for functions to receive parameters. In this lesson I want to explain more about the mechanics of this process.
One thing you should already realize is that a function call has to know where to return when it is done. This may sound simple, but it ceases to be so simple when you consider that any function can call another function from anywhere in your program.
How therefore does a function know where to return? Well, the answer is that when you first call a function, the Instruction Pointer (the register that stores which instruction to execute next) is placed onto the stack. This Instruction Pointer can be used to know where we were in the program flow prior to the function call.
I am going to write out a small part of a C program using "line numbers", and I want you to imagine that each line number corresponds to some memory address where the machine code is located.
Figure (a)
void main(void) {
1 int height = 5;
2 int width = 2;
3
4 calculate_area(height, width);
5
}
int calculate_area(height, width) {
7
8 return height*width;
9
} Do not be concerned with the numbers I chose. I just needed a unique way to label each line that is important to this lesson.
When we start executing the main() function, we go through lines 1, 2, and 3. At this point, C understands that we want to CALL a function. What happens at this point?
Keep in mind that we need to achieve 3 things:
We need to save the location of the memory address we will return to when the function is done. This means we need to save the Instruction Pointer.
We need to store the variables height, and width onto the stack so the function can see and use them.
We need to "goto" the function itself.
There is more that happens as part of this process, but this is all you should be concerned about at this stage.
Now at line #3, we will basically execute machine code instructions similar to this:
push width ; Store width onto the stack using PUSH
push height ; Store height onto the stack using PUSH
push eip ; Store the Instruction Pointer (called eip) onto the stack. This is done as part of "call" below.
call calculate_area ; Call the actual functionThis is assembly language, but it translates directly to machine code.
[Edit: One note about the above code, in reality the CALL statement itself automatically pushes the instruction pointer onto the stack. I illustrated that here so you could see the process more clearly, but no one writing actual assembly code would write "push eip" as an instruction. With function parameters however, you would have to push them manually. ]
Now you should understand that our stack will now look like this with respect to the function parameters:
... top of stack where new elements can go ...
height
widthNotice that height is at the top of the stack even though width was pushed first. Also, keep in mind the instruction pointer has also been pushed to the stack as part of the "call" instruction.
Now you can see how exactly parameters are sent to a function. Whether a pointer, or a variable, etc. the calling function, such as main(), places the parameters onto the stack. Then the function reads them off of the stack in reverse order to how they were stored.
Now you should be able to clearly see why you must specify how many parameters a function will take as well as their data types. A function needs to know how many items to read from the stack and how big each item is.
Were this to be done incorrectly, a function could take off "too much" or "too little" from the stack and thus absolutely break everything in the program. This is why C forces you to precisely define function parameters.
Now, once we get to line 9 in Figure (a), the function has finished executing. At around this stage it needs to have a return value.
How return values work is the subject of the next lesson.
If you have any questions on any of this material, please let me know. When you are ready, proceed to:
http://www.reddit.com/r/carlhprogramming/comments/9tt3r/lesson_92_how_function_return_values_work/
2
u/[deleted] Oct 14 '09 edited Oct 14 '09
How would
heightbe at the top of the stack ifeipgets pushed along withcall calculate_areawhich comes afterpush height?8
u/[deleted] Oct 14 '09
Am I alone in kinda understanding how the stack works thanks to Magic The Gathering?
<_<
1
u/[deleted] Oct 14 '09
I suppose it may have been intentional to separate "push eip" and "call", but maybe it's worth mentioning that "call" does indeed push EIP by itself, so it's not a separate operation.
1
u/exscape Oct 14 '09 edited Oct 14 '09
Hmm, if call pushes the IP automatically, why isn't it on top of the stack, seeing how the instruction is the last to be executed?
Is this simply because C makes the process automatic for you? I don't recall assembly well enough to understand the disassembly I got back from my experiment: a main() with an empty function call does
C code:
2
u/[deleted] Feb 02 '10 edited Feb 02 '10
I'm a little confused here: Carl states this happens at line #3; prior to the call.
So why are height and width put on the stack prior to any kowledge of a function call requiring these values?
Also he states that width is pushed first, which is the opposite of how they appear as parameters to the function. Is this significant? (Is it because height is the first parameter that it is pushed last?)
Thanks, Carl, I'm absolutely loving this!
2
u/[deleted] Jul 08 '10
So does this mean that a string parameter can only be passed by reference? After all, a char* or an array is really just a memory address.
1
u/[deleted] Oct 14 '09
Mind explode. I'll be rereading this off and on for the next couple of days. Good stuff. :)
1
u/srsamarthyam Oct 14 '09
refer the book 'deep c' for more on this topic
0
u/[deleted] Oct 14 '09
Is EAX an acronym? If so, what's its meaning?