56

I read in text books that the stack grows by decreasing memory address; that is, from higher address to lower address. It may be a bad question, but I didn't get the concept right. Can you explain?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Jestin Joy
  • 3,711
  • 4
  • 19
  • 14

4 Answers4

96

First, it's platform dependent. In some architectures, stack is allocated from the bottom of the address space and grows upwards.

Assuming an architecture like x86 that stack grown downwards from the top of address space, the idea is pretty simple:

===============     Highest Address (e.g. 0xFFFF)
|             |
|    STACK    |
|             |
|-------------|  <- Stack Pointer   (e.g. 0xEEEE)
|             |
.     ...     .
|             |
|-------------|  <- Heap Pointer    (e.g. 0x2222)
|             |
|    HEAP     |
|             |
===============     Lowest Address  (e.g. 0x0000)

To grow stack, you'd decrease the stack pointer:

===============     Highest Address (e.g. 0xFFFF)
|             |
|    STACK    |
|             |
|.............|  <- Old Stack Pointer (e.g. 0xEEEE)
|             |
| Newly       |
| allocated   |
|-------------|  <- New Stack Pointer (e.g. 0xAAAA)
.     ...     .
|             |
|-------------|  <- Heap Pointer      (e.g. 0x2222)
|             |
|    HEAP     |
|             |
===============     Lowest Address    (e.g. 0x0000)

As you can see, to grow stack, we have decreased the stack pointer from 0xEEEE to 0xAAAA, whereas to grow heap, you have to increase the heap pointer.

Obviously, this is a simplification of memory layout. The actual executable, data section, ... is also loaded in memory. Besides, threads have their own stack space.

You may ask, why should stack grow downwards. Well, as I said before, some architectures do the reverse, making heap grow downwards and stack grow upwards. It makes sense to put stack and heap on opposite sides as it prevents overlap and allows both areas to grow freely as long as you have enough address space available.

Another valid question could be: Isn't the program supposed to decrease/increase the stack pointer itself? How can an architecture impose one over the other to the programmer? Why it's not so program dependent as it's architecture dependent? While you can pretty much fight the architecture and somehow get away your stack in the opposite direction, some instructions, notably call and ret that modify the stack pointer directly are going to assume another direction, making a mess.

Mehrdad Afshari
  • 414,610
  • 91
  • 852
  • 789
  • 8
    +0.5 for the ASCII art alone. :) But, while answering "how", this doesn't answer "why" very well at all. What makes it so common and/or useful to define stacks this way? – cHao Dec 30 '10 at 07:23
  • 2
    @cHao: Added a couple paragraphs to address the issue. – Mehrdad Afshari Dec 30 '10 at 07:33
  • 2
    @Mehrdad Afshari Some texts say its because we coulld keep the offset non negative since the stack grows downward – Jestin Joy Dec 30 '10 at 13:45
  • @Jestin I don't understand your sentence. Please clarify *what* is done because *which offset* would go negative? – Mehrdad Afshari Dec 31 '10 at 00:47
  • 2
    @Mehrdad Afshari To access the contents of the stack frame, we need only to use non-negative offset value( since the stack grows from Higher to Lower and the top of the stack is always the lowest address). Advanced Compiler Design and Implementation by Steven S.Muchnick page 122 – Jestin Joy Dec 31 '10 at 02:03
  • 1
    @Jestin: I think he is simply mentioning a fact, which is a consequence of the choice of stack being on top and growing down. He doesn't say this is why the design decision is made. As I said before, there *are* architectures that allow the stack to grow upwards (e.g. Intel 8051) or both ways (ARM). – Mehrdad Afshari Dec 31 '10 at 02:07
  • Could it ever happen that the heap grows and get on the stack area and vice versa ? In other words is there any barrier that keeps stack and heap separate ? – Bionix1441 Feb 08 '17 at 17:22
  • @Bionix1441 In the distant past when memory management at the OS level was primitive, this was a possibility. With modern OSes, it protects the two areas. – Richard Jun 13 '17 at 15:56
39

Nowadays it's largely because it's been done that way for a long time and lots of programs assume it's done that way, and there's no real reason to change it.

Back when dinosaurs roamed the earth and computers had 8kB of memory if you were lucky, though, it was an important space optimization. You put the bottom of the stack at the very top of memory, growing down, and you put the program and its data at the very bottom, with the malloc area growing up. That way, the only limit on the size of the stack was the size of the program + heap, and vice versa. If the stack instead started at 4kB (for instance) and grew up, the heap could never get bigger than 4kB (minus the size of the program) even if the program only needed a few hundred bytes of stack.

zwol
  • 135,547
  • 38
  • 252
  • 361
1

Man CLONE : The child_stack argument specifies the location of the stack used by the child process. Since the child and calling process may share memory, it is not possible for the child process to execute in the same stack as the calling process. The calling process must therefore set up memory space for the child stack and pass a pointer to this space to clone(). Stacks grow downward on all processors that run Linux (except the HP PA processors), so child_stack usually points to the topmost address of the memory space set up for the child stack.

0

On x86, the primary reason the stack grows toward decreasing memory addresses is that the PUSH instruction decrements the stack pointer:

Decrements the stack pointer and then stores the source operand on the top of the stack.

See p. 4-511 in Intel® 64 and IA-32 ArchitecturesSoftware Developer’s Manual.

  • I think it's the other way around: the PUSH instruction decrements the stack pointer because the stack grows towards lower memory addresses. This is a design/architecture choice and the implementation of the instructions is a consequence of that. – wovano Nov 27 '22 at 10:28