Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I'm assuming there's a history to it, but why does the stack grow downward?

It seems to me like buffer overflows would be a lot harder to exploit if the stack grew upward...

share|improve this question
3  
stackoverflow.com/questions/1677415/… notes that the stack can grow either way to some degree. –  JB King Feb 29 '12 at 18:14
6  
There is a question just like this one:stackoverflow.com/questions/2035568/…. Matter of factly there is a much better question and answer on this here: stackoverflow.com/questions/664744/… –  Karlson Feb 29 '12 at 18:14
    
The linked question doesn't quite cover the buffer overflow issue. –  deadalnix Feb 29 '12 at 18:19
    
because the heap grows upward. –  tylerl Feb 29 '12 at 18:59
1  
Is memory location 0 at the top or the bottom? –  user1249 Feb 29 '12 at 21:59

3 Answers 3

up vote 12 down vote accepted

I believe it comes from the very early days of computing, when memory was very limited, and it was not wise to pre-allocate a large chunk of memory for exclusive use by the stack. So, by allocating heap memory from address zero upwards, and stack memory from the end of the memory downwards, you could have both the heap and the stack share the same area of memory.

If you needed a bit more heap, you could be careful with your stack usage; if you needed more stack, you could try to free some heap memory. The result was, of course, mostly, spectacular crashes, as the stack would occasionally overwrite the heap and vice versa.

Back in those days there were no interwebz, so there was no issue of buffer overrun exploitations. (Or at least to the extent that the interwebz existed, it was all within high security facilities of the united states department of defense, so the possibility of malicious data did not need to be given much thought.)

After that, with most architectures it was all a matter of maintaining compatibility with previous versions of the same architecture. That's why upside-down stacks are still with us today.

share|improve this answer
2  
Go back further in history and there was no heap, even today, many 8 and 16 bit micro controllers do not have a heap. The stack grew down so the program could be installed in a low memory address, and the stack was the remaining memory. Stack initialization could be performed before program load, simplifying programs. –  mattnz Feb 29 '12 at 23:54
    
Most small microcontrollers have a heap, just not a heap that grows. It hard to justify to use dynamic memory allocation on the heap when you have small amount of RAM ( < 1Kbytes )to work with. Usually the only memory section's size that changes is the stack. –  tehnyit Mar 1 '12 at 9:32

Some hardware has the heap starting at high memory, growing down, while the stack starts at low memory growing up.

HP's PA-RISC hardware, among others, does this: http://www.embeddedrelated.com/usenet/embedded/show/68749-1.php

The venerable Multics Operating System ran on hardware that had (one of possibly many) stacks growing up: see http://www.acsac.org/2002/papers/classic-multics.pdf, end of section 2.3.2:

Third, stacks on the Multics processors grew in the positive direction, rather than the negative direction. This meant that if you actually accomplished a buffer overflow, you would be overwriting unused stack frames, rather than your own return pointer, making exploitation much more difficult.

That's a rather interesting statement. Did buffer overflows become such a huge problem only because of the "customary" procedure-call-stack-frame arrangement? Also, how much of Multics' reputation as Totally Invulnerable was just a fluke of hardware design?

share|improve this answer

program memory is traditionally set up as

code
constants
heap (growing up)
...
stack (growing down)

heap and stack can be exchanged

but buffer overflows can still be exploited if the stack went the other way

taking the classic strcpy as an example

foo(char* in){
char[100] buff;
strcpy(buff,in);
}

with stack memory as

ret foo
arg in
buff array
ret strcpy
buf pointer
in

this would mean that when the copying is done the return address for strcpy is after the buffer (instead of foo's return address) and can be overwritten by whatever is in in

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.