how do stack works in Recursion - c

i don't understand that how stack works in Recursion. During Recursion the parameter of the function get pushed in the stack and return address also pushed on to the stack.The return address and parameter is pushed in the same stack or the return address get pushed in other stack?

Either way is possible. The results are equivalent. The local variables of the function also need space which is managed like a stack, and this again can be the same stack or a different one. This is a possible way to implement a C function call:
Push the function parameters to the parameter stack.
Push the desired return address (generally the address of the instruction after the branch) to the return address stack.
Branch to the function's address.
Push the initial values of the function's local variables to the local variable stack.
And a corresponding way to return from the call:
Pop the local variables from the local variable stack.
Pop from the return address stack.
Branch to the address that was just read.
Pop the parameters from the parameter stack.
If instead of having three separate stacks, there's just one, the procedure above still works. Note that it works because the steps are ordered correctly: with a single stack, you need to do the pops in reverse order from the pushes, whereas with multiple stacks, the order only needs to be consistent within each stack.
In practice, most platforms use a single stack for everything, because it makes memory management easier. Before calling the function, the code creates a stack frame by pushing both the parameters and the return address to the single stack. Pushing the parameters before the return address is typically easier because it uses a relative addressing mode to obtain the return address:
push parameter_1
push parameter_2
…
push program_counter + 2
branch my_function
; first instruction after returning
The first thing the code of the function does is to extend the stack frame to make room for its local variables. Concretely, “extend the stack frame” typically means adding the needed space to the register that points to the the top of the stack. Then, at the end of the function, the code loads the return address into a register, subtracts the length of the stack frame from the stack pointer, and branches to the return address.
There are a lot of possible variations and practical complications. The exact way to call a function is called a calling convention. Most platforms define a calling convention so that code compiled with one compiler can call a function compiled with another compiler. The calling convention can be different for functions with different prototypes: for example, often, some arguments are passed in registers, and the layout of the stack frame may be different for variadic and non-variadic functions. However, some platforms support multiple calling conventions, which requires an additional non-standard annotation on function prototypes (such as __cdecl vs __stdcall on Windows).
One of the possible complications is a shadow stack. Most platforms use a single stack because it's easier to implement and there's less memory management overhead. However, a single stack has the downside that a bug in a function, such as a buffer overflow in an array that is stored on the stack, can easily cause it to overwrite the return address. A shadow stack is an extra copy of the return address in a return address stack which is separate from the main stack. When returning from a function, the code checks that the two copies of the return address are the same, and jumps to an error handler if they aren't. The reason to keep the return address in the main stack is for compatibility. It's the called function that pushes the return address to the return address stack, not the caller; that way the caller doesn't need to know whether the function that it's calling was compiled with shadow stack support or not. The called function gets the return address from the main stack.

Related

Examining local variables returned function

I have a coredump of a process that has crashed (hard to reproduce).
I have figured out that something goes wrong in a function that has just returned (it returned a NULL pointer rather than a non-NULL pointer).
It would be of great help for me to know the contents of the stack variables in that function. I think on most architectures, returning from a function just means changing the stack pointer. In other words, those values are still there (below the stack pointer then if we take x86 as an example).
Can anyone confirm my reasoning is correct and maybe provide an example how do this with gdb?
Does my reasoning also hold for MIPS ?
Local variables might have been stored on stack, but not necessarily. If there is only a small number of variables that fit into registers and code is optimized, then local variables were never saved on stack.
Depending on calling convention used, final values of local variables may still persist in registers.
Disassemble the function in question (you can use objdump -dS to do this, so you can easily correlate source). See how local variables were accessed . Were they stored in memory or registers? Were registers already restored to their value relevant for caller?
If original register value was not restored, you can just examine the register that was used to store local. If it was already restored, then it's probably lost.
If local values were stored to stack, then function prologue (first instructions) should tell you how stack and frame pointer were manipulated. Taking into account that call also saved to stack (PC saved) you can calculate the value of stack/frame pointer used in that function. Then use x to examine memory locations.
Depending on called function, you could also be able to examine its arguments (when called) and recalculate the value of local variables.
You may see local variable that hasn't be optimised using:
info locals
It may not work in a function that already return, though. If you can run that program again, try to put a breakpoint just before the function return.
Otherwise, you can manually investigate the stack using x/x and info register to know the stack pointer address.
You may then browse the stack using up and down.

How C passes value of arguments into functions and results back to the teller?

I'm a extreme beginner of C. And I was just wondering how C programming passes value of arguments into functions and results back to the teller?
The C language says nothing about how argument values are passed into functions, or how results are returned. It merely requires it to work.
An example:
int add1(int n) {
return n + 1;
}
/* ... */
int n = add1(42);
The call add1(42) passes the value 42 (of type int) as an argument to the function add1. This causes execution of the body of add1 to begin.
Inside the body of add1, n is a local variable, initialized to the value that was passed by the current call.
A function call is an expression whose value is whatever value was given to the return statement executed by the function. Execution of the return statement causes the execution of the function to terminate; execution continues with the caller.
The underlying mechanism by which these values are passed around is not specified. On some implementations, values might be pushed onto the "stack". On others, they might be copied via CPU registers.
Passing the values by carrier pigeon would be perfectly legal, as long as the program's behavior is as specified by the C standard.
This is called a "calling convention." Different platforms define different calling conventions, and C compilers will generally aim to follow the established convention for the platform. There isn't any one way that "C does it," per se. There are a lot of things the C compiler intentionally doesn't specify, and this is one of them. The idea is that a particular implementation will know best what calling convention to use for the target platform.
Broadly speaking, the two main techniques are registers or on the stack. The C standard does not specify which technique should be used, but pragmatically speaking, you can think of parameter passing as using a stack.
The stack is often implemented in hardware as a register, the stack pointer (SP). Just like your other registers, the accumulators and index registers, it holds a binary value. The value in the SP register is used in the machine's PUSH and POP instructions which access the memory cell whose address is in the SP register and also modify the register's value to move the pointer up or down to the next cell.
So for simplicity, lets consider just int values, so they're all the same size and we can safely think of the memory cells as an array of ints.
To make a function call, such as
f(a, b);
First the arguments are pushed on the stack, assuming these values are in registers A and B.
PUSH B
PUSH A
Then control is passed to the function. CALL is often a single instruction which pushes the current instruction pointer on the stack and then performs a JUMP to the first byte of f.
CALL f
f will then access its arguments, mindful that the return address (the code location for the function to return to) is also on the stack.
When f is finished, it will either return its value on the stack, or more likely it will simply use a register as an optimization since the value is probably conveniently already in a register. It also needs to pop its argument from the stack as part of returning. This is often a single instruction which accepts an argument specifying how many extra cells to POP.
RET 2
If it returns the value on the stack, it will return differently. It now needs to index the stack, and request one fewer cell to be POPped.
MOVE A,(SP)-2
RET 1

Does C destroy return variable before the closing brace?

Somebody told me that in C (and C++) that the variable present in a return statement is destroyed before closing brace of the function.
Ex -
int func() {
int a = 10;
return a; // I was told that a is destroyed here
}
Does it really happen that way? If yes, how does the function return value to the calling function?
My intuition tells me that the variable value is pushed on to stack at the return value and when it goes back to the calling function, the stack top is popped there by getting the return value. Not sure if I'm correct.
Does C destroy return variable before the closing brace?
Yes ... sort of.
Local variables go out of scope at the end of a method, and after that, they cease to be accessible.
In C, that simply means that the storage for the variable itself becomes available for other uses. But there is no active "destruction" of the variable.
In C++, the variable's destructor (if there is one) will be invoked when the variable goes out of scope.
At an implementation level, the storage space for local variables is typically managed using a stack. But I don't think this is mandated by the respective language specifications.
It is also important to note that we are talking about variables, not values. In your example, the value of the variable is going to be returned to the caller (vide the return statement) and will continue to exist beyond the } ...
how does the function return value to the calling function?
Your intuition is right (partially). In some architecture the value is stored at stack and get popped when returning to the caller. But keep in mind that a value is returned from a function, not the variable itself.
C: How to Program: Ch-5: C Functions:
When a program calls a function, the called function must know how to return to its
caller, so the return address of the calling function is pushed onto the program execution stack (sometimes referred to as the function call stack).
The program execution stack also contains the memory for the local variables used in
each invocation of a function during a program’s execution. This data, stored as a portion of the program execution stack, is known as the activation record or stack frame of the function call. When a function call is made, the activation record for that function call is pushed onto the program execution stack. When the function returns to its caller, the activation record for this function call is popped off the stack and those local variables are no longer known to the program.
EDIT: As others mentioned is comments that this is implementation specific I changed my mind.
For x86 wiki says:
Calling conventions describe the interface of called code:
1. The order in which atomic (scalar) parameters, or individual parts of a complex parameter, are allocated
2. How parameters are passed (pushed on the stack, placed in registers, or a mix of both)
3. Which registers the callee must preserve for the caller
4. How the task of preparing the stack for, and restoring after, a function call is divided between the caller and the callee
There are often subtle differences in how various compilers implement these conventions.

How do called functions return to their caller, after being called?

I read that when a function call is made by a program, the called function must know how to return to its caller.
My question is: How does the called function know how to return to its caller? Is there a mechanism working behind the scenes through the compiler?
The compiler obeys a particular "calling convention", defined as part of the ABI you're targeting. That calling convention will include a way for the system to know what address to return to. The calling convention usually takes advantage of the hardware's support for procedure calls. On Intel, for example, the return address is pushed to the stack:
...the processor pushes the value of the EIP register (which contains the offset of the instruction following the CALL instruction) on the stack (for use later as a return-instruction pointer).
Returning from a function is done via the ret instruction:
... the processor pops the return instruction pointer (offset) from the top of the stack into the EIP register and begins program execution at the new instruction pointer.
To contrast, on ARM, the return address is put in the link register:
The BL and BLX instructions copy the address of the next instruction into lr (r14, the link register).
Returns are commonly done by executing movs pc, lr to copy the address from the link register back into the program counter register.
References:
Intel Software Developers Manual
ARM Information Center
The compiler knows how to call a function and which calling convention is used. For example in C the arguments for a function are pushed on the stack. The caller is repsonsible for clearing the stack, so the called function doesn't have to remove the arguments. Other calling conventions can include pushing the arguments on the stack and the called function has to clean it. In this case, the generated code is such, that the function corrects the stack before it can return. Ohter calling conventions may pass the arguments in registers, so in such a case the called function also doesn't have to take care.
The CPU has a mechanism to call a subroutine. This will store the current execution address on the stack and then transfer processing to the new address. When the function is done it executes a return statement, which will fetch the caller address and resume execution there.
If the return address is destroyed, because the stack is not properly cleaned uo, or the memory is overwritten, then you get undefined behaviour. Of course the exact implementation details vary depending on the platform which is used.
This is made possible by the stack(especially on Intel-like systems). Let's say that we have a method caller that includes, say, an int that it keeps locally.
When caller( calls target( that int must be saved. It is placed on the stack, along with the address from which the call is made. target( can perform its logic, create its own local variables, and call other methods. Its local variables will be placed onto the stack along with the call's address.
When target( ends, the stack is "unrolled". The top of the stack containing target('s local variables is removed.
When methods recurse too far, the stack may grow too large, and a "stack overflow" may occur.
It requires cooperation between the callee and the caller.
The caller agrees to give the address that the callee should return to to the callee (usually by pushing it on the stack, or by passing it in a register), and the callee agrees to return to that address when it's finished executing.

Function calls, the stack

So I don't know why but I learned that when you call a function and pass an argument to it, it deals with it on the stack(processor?).
Can someone please explain it?
then how does it change values of variables, blocks of memory and so on?
There is no guarantee that parameters are passed on the stack, it's architecture and compiler dependent.
As to how values and memory get changed -- when you call a function that must make changes that are seen by the caller, it's normal that what you provide is not the actual value, but rather the address of (pointer to) that value. As long as the function knows the proper memory location it can make these changes.
Stack is used in most cases to pass arguments to function. The reason for using it is that you are not bound to fixed memory places (for arguments) to have your function functional. If you had function that could take arguments from fixed memory you would probably only be able to run it if the memory was free and you would be able to run just one instance of it. Stack gives you the possibility to store your arguments to current context of your program at any time. On x86 processors there is register that points to end of the stack and other register that points to the begining. Those are actualy just addresses to main memory where you want your stack to reside.
There is PUSH instruction that moves the stack-end register to the next place and stores specified data (could be value from other register or at some address or direct value) to address pointed by stack-end resgister. The other instruction is POP and it works the same just the other way around. This way, if you stick to the plan and keep track of what you pushed to stack, you can have your functions work from any context.
There are some other less used options to pass arguments like via registers, which are used for example by bios interrupts. If you want to know more about this I suggest you read something on "Calling conventions".
Lets start with this suppose you have a function
int foo(int value) {
int a = 10;
return a;
}
So whenever a function call is made OS needs some memory space to allocate the local variables of the function int a in this case and arguments to the function passed int value in this case. This memory requirement is fulfilled by allocating memory on stack. A stack is nothing but a memory region allocated to each process and it actually behaves as a stack data structure(LIFO).
Now the question arises what all things are stored on stack when a function call is made. The first thing pushed on the stack are the arguments passed to the function in reverse order(if more then one).
2. Then the return address of the function which called this function (because once this function foo completes execution it should return back to the place in the code from where it was called)
3. Finally local variables of the function called are pushed on the stack.
Once the called function completes executing the code it returns back to the return address previously stored on the stack and thus we say function call completes or returns.
In this case the function has a return value which it passes back to the callee function.
The space is then free to use and can be overwritten in the subsequent function calls.
(Now if you connect the dotes you can realize why local variables(automatic variables) in a function have scope limited to the life of the function call (you asked a SO question related to scope which was closed) because once a call returns the memory space allocated for these locale variable is gone(it is still there but you cant access them once a function returns) so life of these automatic variable int a in this case limits till foo() returns to the callee function.
Side Note:: I have read many questions that you have posted in SO. I guess you are trying to learn C and basic working of the underlying hardware and OS in general and the confusion in between them is killing you.
I would suggest you some pointers apart from the answer to this question to read and understand which will give you lots of insight into the questions you are facing.
For C refer K&R it is the best book.
In the starting read little bit about OS concepts(Memory handling, Virtual Memory in particular)
Try imagine the working of a system in broad sense as in how different components are interacting.
Some good links for understanding memory related stuff and system internals http://duartes.org/gustavo/blog/best-of
and if you want to dive into stack space for a function call try this link http://www.binarypirates.in/2011/02/17/understanding-function-stack-in-c/
Hope this helps

Resources