Sé que en las arquitecturas con las que estoy familiarizado (x86, 6502, etc.), la pila normalmente crece hacia abajo (es decir, cada elemento que se introduce en la pila da como resultado un SP decrementado, no uno incrementado).
Me pregunto cuál es la razón histórica de esto. Sé que en un espacio de direcciones unificado, es conveniente comenzar la pila en el extremo opuesto del segmento de datos (digamos), por lo que solo hay un problema si los dos lados chocan en el medio. Pero, ¿por qué la pila obtiene tradicionalmente la parte superior? ¿Especialmente dado que esto es lo opuesto al modelo "conceptual"?
(Y tenga en cuenta que en la arquitectura 6502, la pila también crece hacia abajo, aunque está limitada a una sola página de 256 bytes, y esta elección de dirección parece arbitraria).
fuente
Una buena explicación que escuché fue que algunas máquinas en el pasado solo podían tener compensaciones sin firmar, por lo que querría que la pila creciera hacia abajo para poder golpear a sus locales sin tener que perder la instrucción adicional para simular una compensación negativa.
fuente
Stanley Mazor (arquitecto de 4004 y 8080) explica cómo se eligió la dirección de crecimiento de la pila para 8080 (y eventualmente para 8086) en "Microprocesadores Intel: 8008 a 8086" :
fuente
Una posible razón podría ser que simplifica la alineación. Si coloca una variable local en la pila que debe colocarse en un límite de 4 bytes, simplemente puede restar el tamaño del objeto del puntero de la pila y luego poner a cero los dos bits inferiores para obtener una dirección alineada correctamente. Si la pila crece hacia arriba, asegurar la alineación se vuelve un poco más complicado.
fuente
A - B
podría implementarse conceptualmente comoA + (-B)
(es decir, un paso de negación separado paraB
), no lo es en la práctica.IIRC la pila crece hacia abajo porque el montón crece hacia arriba. Podría haber sido al revés.
fuente
realloc(3)
necesita más espacio después de un objeto para simplemente extender el mapeo sin copiar. La reasignación repetida del mismo objeto es posible cuando le sigue una cantidad arbitraria de espacio no utilizado.Creo que es puramente una decisión de diseño. No todos crecen hacia abajo: consulte este hilo SO para obtener una buena discusión sobre la dirección del crecimiento de la pila en diferentes arquitecturas.
fuente
Creo que la convención comenzó con el IBM 704 y su infame "registro de decremento". El habla moderna lo llamaría un campo de compensación de la instrucción, pero el punto es que bajaron , no subieron .
fuente
Solo 2c más:
Más allá de todas las razones históricas mencionadas, estoy bastante seguro de que no hay ninguna razón válida en los procesadores modernos. Todos los procesadores pueden tomar compensaciones firmadas, y maximizar la distancia de pila / pila es bastante discutible desde que comenzamos a trabajar con múltiples subprocesos.
Personalmente, considero que esto es un error de diseño de seguridad. Si, digamos, los diseñadores de la arquitectura x64 hubieran invertido la dirección del crecimiento de la pila, la mayoría de los desbordamientos del búfer de pila se habrían eliminado, lo cual es un gran problema. (ya que las cuerdas crecen hacia arriba).
fuente
No estoy seguro, pero hice algo de programación para VAX / VMS en el pasado. Me parece recordar una parte de la memoria (¿el montón?) Subiendo y bajando la pila. Cuando los dos se conocieron, entonces te quedaste sin memoria.
fuente
Una ventaja del crecimiento de la pila descendente en un sistema integrado mínimo es que una sola porción de RAM se puede mapear de forma redundante tanto en la página O como en la página 1, lo que permite que se asignen cero variables de página a partir de 0x000 y que la pila crezca hacia abajo desde 0x1FF, maximizando la cantidad que tendría que crecer antes de sobrescribir las variables.
Uno de los objetivos de diseño originales del 6502 era que podía combinarse con, por ejemplo, un 6530, lo que da como resultado un sistema de microcontrolador de dos chips con 1 KB de ROM de programa, temporizador, E / S y 64 bytes de RAM compartidos. entre las variables de pila y página cero. En comparación, el sistema integrado mínimo de esa época basado en un 8080 o 6800 sería de cuatro o cinco chips.
fuente