开发者

What are stacks in DRAM (what happens during recursion)?

I just want to get a better understanding of what a stack is in the address space (i.e you have code/text, heap,开发者_Python百科 data, and a stack)

basically my understanding is that a stack contains local variables, but then what is the difference between what the data contains and what a stack contains? isn't data variables as well?

If a program has a recursive call to a function a() does it mean that for every level of recursion there is a new stack?


A stack is usually different to data only in the way it's used and managed. While non-local variables themselves usually have a known specific memory location, things on the stack are found relative to a register (stack pointer or base pointer or some such).

A stack usually contains local variables, passed parameters and control information for managing the stack itself.

And, if you make a recursive call, you don't get a new stack, just a new stack frame. A frame is a chunk of the stack relevant to the current stack depth (whether that's by recursion or just regular function calls). That's what makes recursion possible, the fact that the variables for a given depth are independent of those for other depths.

Keep in mind that this is all dependent, of course, on the architecture. My description above is a common case but there are architectures where stacks are done differently, such as SPARC, the System z and RCA1802.

More details can be found here (how frames work) and here (weird stacks).


First, a small clarification. Stacks are not necessarily in DRAM. they are just a structure that can be formed in any memory: DRAM, caches, disk.

To understand a stack, you should first understand what is a stack. It is like a stack of trays, the properties that make it a stack are:

  • You can only access the top element of the stack
  • It is Last In First Out, i.e., when you go to get a data from a stack you get the data that was stored last on the stack.

The act of storing something in a stack is called PUSH and removing it is called a POP. Say I do the following to an empty stack:

PUSH A
PUSH B
PUSH C

Then the stack will contain

C - Top
B
A

Now if I execute a POP (notice there is no operand here), it will return C and the stack will contain

B -- top of stack
A

So stack in processors is just a hardware implementation of the above algorithm.

A register contains the address of the top of stack called stack point The ISA (Instruction Set Architecture) provides PUSH and POP instructions to access the stack variables as I showed above.

This is a very useful construct. A stack is used to store local variables, basically temporary data that you want to remove at the end of a function call. It specifically helps with function calls. When a function is called, the variables of the newly called function's local variables are pushed on the stack.

foo(){
    int a;   
    int b;    // both registers containing a and b are PUSHed here on the stack 
    c = bar(); // pop the stack to get value of c 
    print c
}

bar(){
   int z; // local variables pushed on top of the stack
   z = ... 
   return z; // pop all local variables of bar(), then push z on the stack 
}

I hope the above helps.


The following program should help you understand what is going on. You will see pointer examples of text, bss, heap, and stack. Text is usually executable code, bss are static/global variables, heap is dynamically allocated memory, stack contains local variables.

#include <stdlib.h>
#include <stdio.h>

#define TESTS 10
int numfeed = 0;
int numdead = 0;

recurse(int x)
{
  u_int pattern=0xfeedface;
  u_int *otherpattern = malloc(4);
  *otherpattern = 0xdeadbeef;

  printf("Feedface %d is at %p\n",x,&pattern);
  printf("deadbeef %d is at %p\n",x,otherpattern);

  if (--x == 0)
  {
    int *off;

    for(off = &pattern;numfeed<TESTS;off++)
    {
      if (*off == 0xfeedface)
        printf("Found feedface #%d at %p\n", ++numfeed, off);
      if (*off == 0xdeadbeef)
        printf("Found deadbeef #%d at %p -- WHAT?!?!!?!?\n", ++numdead, off);
    }
  }
  else
  {
    recurse(x);
  }
  // Not freeing otherpattern intentionally.
}


main()
{
  u_int *otherpattern = malloc(4);
  *otherpattern = 0xdeadbeef;
  int *off;

  recurse(TESTS);

  for(off = otherpattern+1;numdead<TESTS;off++)
  {
    if (*off == 0xfeedface)
      printf("Found feedface #%d at %p -- WHAT?!?!!!?!?\n", ++numfeed, off);
    if (*off == 0xdeadbeef)
      printf("Found deadbeef #%d at %p\n", 1+TESTS-(++numdead), off);
  }

  printf("numfeed is at %p\n",&numfeed);
  printf("recurse is at %p\n",&recurse);
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜