From http://www.learncpp.com/cpp-tutorial/79-the-stack-and-the-heap/
Here is the sequence of steps that takes place when a function is called:
- The address of the instruction beyond the function call is pushed onto the stack. This is how the CPU remembers where to go after the function returns.
- Room is made on the stack for the function’s return type. This is just a placeholder for now.
- The CPU jumps to the function’s code.
- The current top of the stack is held in a special pointer called the stack frame.
- Everything added to the stack after this point is considered “local” to the function.
- All function arguments are placed on the stack.
- The instructions inside of the function begin executing.
- Local variables are pushed onto the stack as they are defined.
I am not sure how point #6 works. If all function arguments are placed on the stack, how are they accessed?
If for example, there are three arguments a
, b
and c
and are placed on stack like this from top
| a |
| b |
| c |
| |
...
|___|
Now what happens when the function wants to access c
? Are a
and b
popped out?
It uses the stack pointer and a relative adress to point out c.
The stack is a metaphoric stack. Remember it is still a RAM, so you can access each address without popping the rest, if you know what you are looking for.
Since the automatic variable's size is known at compile time - the compiler marks
offset
for each variable, the offset is determined from where the automatic variables section on stack start [or the stack's head, both are valid and the specific implementation depends might depend on architecture], and it access them by merely:start + offset
for each variable's offset.No they are not. The stack pointer (typically the
esp
registry) points toa
,esp+8h
points tob
,esp+16h
points toc
and so on. There's no need fora
to be popped.Note that this is an implementation detail. You shouldn't worry about these. The number I've given is purely theoretical, on some architectures descending addresses are given to latter parameters, on others the other way around. There's no guarantee this happens.
EDIT: It seems to me like that's not a very reliable source of information. It speaks of stack and heap, but these are implementation details, and might not even be there.
There's no constraint in the standard for anything to be implemented via a stack either. For example, I have the following code generated:
So you see, there's no stack there. The runtime has direct access to the elements:
dword ptr [x]
, etc.