- Angelfire

Anuncio
STACK
El stack de memoria es una parte importante del sistema de memoria de todos
los microprocesadores. Contiene los datos en forma temporal y almacena las
direcciones de retorno para los procedimientos o subrutinas. La pila de memoria es del
tipo LIFO (último en entrar, primero en salir) en los microprocesadores 8086-80486.
Los datos se colocan en la pila con una instrucción PUSH y se recuperan con una
instrucción POP. La instrucción CALL aprovecha la pila para “salvar” la dirección de
retorno del procedimiento, y la RET para “recuperar” de la pila la dirección de retorno
del procedimiento.
La pila de memoria se mantiene con dos registros: el apuntador de pila (SP o
ESP) y el segmento de pila (SS).
PUSH/POP
Las instrucciones PUSH y POP son importantes pues almacenan y recuperan
datos de la memoria de pila LIFO. Los microprocesadores 8086-80486 tienen seis
formas de instrucciones PUSH y POP: registro, memoria, inmediata, registro de
segmentos, banderas y todos los registros. Las formas PUSH y POP inmediatas y las
formas PUSHA y POPA (todos los registros) no están disponibles en los primeros
microprocesadores 8086-8088 pero sí en los 80286, 80386 y 80486.
El direccionamiento por registros permite transferir cualquier registro de 16 bits
desde o hacia la pila. En los 80386/80486 los registros extendidos de 32 bits y las
banderas (EFLAGS) también pueden transferirse a y desde la pila. El direccionamiento
a memoria almacena los contenidos de una localidad de memoria de 16 bits (32 bits en
los 80386/80486) en la pila o transferir datos de la pila a una localidad de memoria. El
direccionamiento inmediato permite salvar datos inmediatos dentro de la pila, pero no
recuperarlos. El direccionamiento por registros de segmento permite salvar o recuperar
la pila. Las banderas se pueden salvar en la pila o recuperar de ella así como el
contenido de todos los registros.
PUSH
La instrucción PUSH transfiere 2 o 4 bytes según sea el registro o el tamaño de
la localidad de memoria. La fuente de los datos puede ser cualquier registro interno de
16 o de 32 bits, datos inmediatos, cualquier registro de segmento o 2 bytes
cualesquiera de datos de la memoria. También hay una instrucción PUSHA que salva
el contenido del grupo de registros internos, excepto el de segmento de pila, en la pila.
La instrucción PUSHAD y POPAD salvan y recuperan el contenido del grupo de
registros de 32 bits que hay en los microprocesadores 80386 y 80486.
POP
La instrucción POP efectúa, a la inversa, las acciones de la instrucción PUSH.
La instrucción POP transfiere datos de la pila y los carga en los destinos que pueden
ser un registro de 16 bits, un registro de segmento o una localidad de 16 bits en la
memoria. En los 80386/80486, POP también puede transferir datos de 32 bits de la pila
y utiliza direcciones de 32 bits. La instrucción POP no está disponible como POP
inmediato. La instrucción POPFD elimina un número de 32 bits de la pila y la coloca
en el registro extendido de banderas. Una instrucción POPAD recupera los registros de
32 bits desde la pila.
Inicialización de la pila
Cuando se inicializa la zona de la pila, se cargan el registro (SS) de segmento de
pila y el registro (SP) apuntador de pila. Se acostumbra designar una zona de la
memoria como segmento de pila, para lo cual se carga SS con la localidad del fondo
del segmento de pila. Por ejemplo, si el segmento de pila se encuentra en las
localidades 10000H-1FFFFH de la memoria, se carga SS con un 1000H.
El problema de Josephus
Cuenta una leyenda sobre el historiador Josephus Flavius que, durante las guerras
judeo-romanas, él y otros 40 soldados judíos quedaron atrapados en una cueva
rodeados por los romanos.
Visto que tenían pocas posibilidades de salir con vida, decidieron suicidarse. Josephus
y un amigo suyo no estaban muy felices con esa idea. Así pues, propusieron que si
había que hacerlo, se hiciera con cierto orden: se colocarían en círculo y se irían
suicidando por turno cada tres empezando a contar por uno determinado.
Josephus y su amigo se colocaron de tal forma que fueron los dos últimos y así, como
ya nadie les podía llevar la contraria, decidieron seguir viviendo.
Algoritmo Recursivo
Aquí propongo un algoritmo recursivo que me parece es muy eficiente para resolver
este problema. No sé si alguien ya haya propuesto un algoritmo recursivo también, o si
haya uno parecido o igual a este. Estuve buscando pero no encontré nada.
int flavius (int n, int k) {
return (n = = 1) ? 0 : (k + flavius(n-1, k))%n);
}
int sobreviviente = 1 + flavius(n, k);
donde n es el número de soldados y k es el número de veces que quieras que se vayan
muriendo.
Bibliografía
B. BREY, Barry “ Los microprocesadores INTEL”, México, Prentice Hall, 1994, 836p.
http://descartes.cnice.mecd.es/m_Numeros/problema_josephus/ProblJosephus.htm
Documentos relacionados
Descargar