¿Por qué la pila crece hacia abajo?

31

Supongo que hay una historia, pero ¿por qué la pila crece hacia abajo?

Me parece que los desbordamientos del búfer serían mucho más difíciles de explotar si la pila creciera hacia arriba ...

Mehrdad
fuente
3
stackoverflow.com/questions/1677415/… señala que la pila puede crecer de cualquier manera hasta cierto punto.
JB King
66
Hay una pregunta como esta: stackoverflow.com/questions/2035568/… . De hecho, hay una pregunta y respuesta mucho mejor sobre esto aquí: stackoverflow.com/questions/664744/…
Karlson
La pregunta vinculada no cubre el problema del desbordamiento del búfer.
deadalnix
1
porque el montón crece hacia arriba.
tylerl
2
¿La ubicación de memoria 0 está en la parte superior o inferior?

Respuestas:

21

Yo creo que viene desde los primeros días de la informática, cuando la memoria era muy limitado, y no era aconsejable comprobar la validez de asignar una gran cantidad de memoria para uso exclusivo de la pila. Entonces, al asignar memoria de montón desde la dirección cero hacia arriba, y apilar memoria desde el final de la memoria hacia abajo, puede hacer que tanto el montón como la pila compartan la misma área de memoria.

Si necesita un poco más de almacenamiento dinámico, puede tener cuidado con el uso de su pila; Si necesita más pila, puede intentar liberar algo de memoria de almacenamiento dinámico. El resultado fue, por supuesto, en su mayoría, accidentes espectaculares, ya que la pila ocasionalmente sobrescribía el montón y viceversa.

En aquellos días no había interwebz, por lo que no había problemas de explotación de desbordamiento de búfer. (O al menos en la medida en que existía la interwebz, todo estaba dentro de las instalaciones de alta seguridad del departamento de defensa de los Estados Unidos, por lo que no era necesario pensar mucho en la posibilidad de datos maliciosos).

Después de eso, con la mayoría de las arquitecturas, todo era cuestión de mantener la compatibilidad con versiones anteriores de la misma arquitectura. Es por eso que las pilas al revés todavía están con nosotros hoy.

Mike Nakis
fuente
8
Retroceda más en la historia y no hubo almacenamiento dinámico, incluso hoy en día, muchos microcontroladores de 8 y 16 bits no tienen almacenamiento dinámico. La pila creció para que el programa pudiera instalarse en una dirección de poca memoria, y la pila era la memoria restante. La inicialización de la pila podría realizarse antes de cargar el programa, simplificando los programas.
mattnz
1
La mayoría de los microcontroladores pequeños tienen un montón, pero no un montón que crece. Es difícil justificar el uso de la asignación dinámica de memoria en el montón cuando tiene una pequeña cantidad de RAM (<1Kbytes) para trabajar. Por lo general, el único tamaño de la sección de memoria que cambia es la pila.
tehnyit
7

La memoria del programa se configura tradicionalmente como

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

el montón y la pila se pueden intercambiar

pero los desbordamientos del búfer aún pueden explotarse si la pila se fue al revés

tomando el clásico strcpycomo ejemplo

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

con memoria de pila como

ret foo
arg in
buff array
ret strcpy
buf pointer
in

esto significaría que cuando se realiza la copia, la dirección de retorno para strcpyestá después del búfer (en lugar de foola dirección de retorno) y se puede sobrescribir por lo que esté enin

monstruo de trinquete
fuente
4

Algunos hardware tienen el montón comenzando en memoria alta, creciendo hacia abajo, mientras que la pila comienza en memoria baja creciendo.

El hardware PA-RISC de HP, entre otros, hace esto: http://www.embeddedrelated.com/usenet/embedded/show/68749-1.php

El venerable sistema operativo Multics se ejecutaba en hardware que tenía (una de muchas) pilas durante su crecimiento: consulte http://www.acsac.org/2002/papers/classic-multics.pdf , final de la sección 2.3.2:

Tercero, las pilas en los procesadores Multics crecieron en la dirección positiva, en lugar de en la dirección negativa. Esto significaba que si realmente lograba un desbordamiento del búfer, estaría sobrescribiendo los cuadros de pila no utilizados, en lugar de su propio puntero de retorno, haciendo que la explotación sea mucho más difícil.

Esa es una declaración bastante interesante. ¿Los desbordamientos del búfer se convirtieron en un problema tan grande solo debido a la disposición "habitual" del procedimiento-llamada-pila-marco? Además, ¿cuánto de la reputación de Multics como Totalmente invulnerable fue solo una casualidad del diseño de hardware?

Bruce Ediger
fuente
Bueno, no tener pila (s) ejecutable (s) probablemente ayudó a Multics tanto como la dirección inteligente de pila, y por supuesto con muchos programas escritos en PL / 1, los desbordamientos de cadenas tampoco fueron realmente un problema.
Greg A. Woods, el