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