2009-03-20 16 views

Respuesta

126

crecimiento de la pila por lo general no dependen del sistema operativo en sí, sino en el procesador que se está ejecutando. Solaris, por ejemplo, se ejecuta en x86 y SPARC. Mac OSX (como usted mencionó) se ejecuta en PPC y x86. Linux funciona en todo, desde mi gran honkin 'System z at work hasta puny little wristwatch.

Si la CPU ofrece algún tipo de opción, la convención de llamadas ABI utilizada por el sistema operativo especifica qué opción debe realizar si desea que su código llame al código de todos los demás.

Los procesadores y su dirección son:

x86   down 
SPARC  selectable. The standard ABI uses down. 
PPC   down, I think. 
System z  in a linked list, I kid you not. 
      (but still down, at least for zLinux). 
ARM   selectable, but Thumb2 has compact encodings only for down (LDMIA (increment after)/STMDB (decrement before)) 
Mostek6502 down (but only 256 bytes). 
RCA1802A  any way you want, subject to SCRT implementation. 
PDP11  down. 

mostrando mi edad en esos últimos, el 1802 fue el chip se utiliza para controlar las primeras lanzaderas (detección de si las puertas estaban abiertas, sospecho, sobre la base de el poder de procesamiento que tenía :-) y mi segunda computadora, el COMX-35 (siguiendo mi ZX80).


PDP11 detalles recogidos de here.

La arquitectura SPARC utiliza un modelo de registro de ventana deslizante. Los detalles arquitectónicamente visibles también incluyen un búfer circular de ventanas de registro que son válidas y se almacenan en caché internamente, con trampas cuando se sobrepasa/subdesborda. Ver here para más detalles. Como the SPARCv8 manual explains, las instrucciones GUARDAR y RESTAURAR son como las instrucciones ADD más la rotación de la ventana de registro. Usar una constante positiva en lugar del negativo habitual daría una pila ascendente.


La técnica SCRT antes mencionado es otro - el 1802 utilizaron algunos o Es dieciséis registros de 16 bits para SCRT (llamada estándar a la técnica de retorno). Uno era el contador del programa, puede usar cualquier registro como la PC con la instrucción SEP Rn. Uno era el puntero de la pila y dos se establecieron siempre para apuntar a la dirección del código SCRT, una para la llamada y otra para el retorno. No registro fue tratado de una manera especial. Tenga en cuenta que estos detalles son de memoria, es posible que no sean totalmente correctos.

Por ejemplo, si R3 era la PC, R4 era la dirección de llamada SCRT, R5 era la dirección de retorno SCRT y R2 era la "pila" (citas como se implementa en el software), SEP R4 configuraría R4 para ser la PC y comienza a ejecutar el código de llamada SCRT.

Sería entonces tienda de R3 en la R2 "pila" (creo que R6 se utiliza para el almacenamiento temporal), ajustándolo hacia arriba o hacia abajo, agarra los dos bytes siguientes R3, ellos cargar en R3, y luego hacer SEP R3 y estar corriendo en la nueva dirección.

Para regresar, sería SEP R5 que tirar de la antigua dirección de la pila R2, agregue dos a él (para saltar los bytes de dirección de la llamada), cargarlo en R3 y SEP R3 para empezar a ejecutar el código anterior.

Muy difícil de entender después de todo el código basado en la pila 6502/6809/z80, pero sigue siendo elegante en una especie de bang-tu-cara contra la pared. Además, una de las principales características de venta del chip fueron 16 registros de 16 bits, e inmediatamente se perdieron 7 de ellos (5 para SCRT, dos para DMA e interrupciones de la memoria). Ahh, el triunfo del marketing sobre la realidad.

El sistema z es en realidad bastante similar, utilizando sus registros R14 y R15 para llamada/devolución.

+3

Para agregar a la lista, ARM puede crecer en cualquier dirección, pero puede configurarse para uno u otro mediante una implementación particular de silicio (o puede dejarse seleccionable por software). Los pocos con los que he tratado siempre han estado en modo de crecimiento. –

+0

Guau, esto es revelador: siempre he supuesto que no funciona para todas las arquitecturas. ¡Listas enlazadas! –

+0

Creo que PPC es seleccionable, pero crece en OS X (ya que los 68k con los que Mac se ejecutó antes tenían una pila descendente). – Michael

4

pila crece hacia abajo en x86 (definida por la arquitectura, incrementos pop puntero de pila, empujan decrementos.)

2

Se reduce porque la memoria asignada al programa tiene los "datos permanentes", es decir, el código para el programa en la parte inferior, y luego el montón en el medio. Necesitas otro punto fijo desde el que hacer referencia a la pila, por lo que te deja en la cima. Esto significa que la pila crece, hasta que es potencialmente adyacente a los objetos en el montón.

21

En C++ (adaptable a C) stack.cc:

static int 
find_stack_direction() 
{ 
    static char *addr = 0; 
    auto char dummy; 
    if (addr == 0) 
    { 
     addr = &dummy; 
     return find_stack_direction(); 
    } 
    else 
    { 
     return ((&dummy > addr) ? 1 : -1); 
    } 
} 
+11

Guau, ha pasado mucho tiempo desde que vi la palabra clave "auto". – paxdiablo

+4

(& dummy> addr) no está definido. El resultado de alimentar dos punteros a un operador relacional se define solo si los dos punteros apuntan dentro de la misma matriz o estructura. – sigjuice

+1

Intentar investigar el diseño de tu propia pila, algo que C/C++ no especifica en absoluto, es "poco práctico" para empezar, así que realmente no me importa eso. Sin embargo, parece que esta función solo funcionará correctamente una vez. – ephemient

6

la ventaja de crecer hacia abajo es en los sistemas más antiguos de la pila era típicamente en la parte superior de la memoria. Los programas normalmente llenaban la memoria comenzando desde abajo, por lo que este tipo de gestión de memoria minimizaba la necesidad de medir y colocar la parte inferior de la pila en algún lugar sensato.

+0

No es una 'ventaja', una tautología realmente. – EJP

3

En MIPS no hay instrucción push/pop. Todos los impulsos/pops se realizan de forma explícita mediante load/store con respecto al puntero de la pila y luego ajustan manualmente el puntero $sp. Sin embargo, como todos los registros (excepto $0) son de propósito general, en teoría cualquier registro puede ser un puntero de pila, y la pila puede crecer en cualquier dirección que desee el programador. MIPS ABIs típicamente crecen hacia abajo.

En Intel 8051 crece la pila, probablemente porque el espacio de memoria es tan pequeño (128 bytes en la versión original) que no hay un montón y no es necesario colocar la pila encima para separarla del montón creciendo desde abajo.

3

En la mayoría de los sistemas, la pila crece, y mi artículo en https://gist.github.com/cpq/8598782 explica POR QUÉ crece. La razón es que es el diseño óptimo de dos regiones de memoria en crecimiento (montón y pila).

+0

esa idea parece estar muerta ahora :( – Ven

+1

@Ven, he corregido el enlace – valenok

Cuestiones relacionadas