Little man computer

De Wikipedia, la enciclopedia libre
Esta es una versión antigua de esta página, editada a las 08:23 22 mar 2020 por Aosbot (discusión · contribs.). La dirección URL es un enlace permanente a esta versión, que puede ser diferente de la versión actual.

El Little Man Computer (LMC, en inglés: "Computadora del hombre pequeño") es un modelo educativo de computadora, creado por el Dr. Stuart Madnick en 1965.[1]​ El LMC se utiliza normalmente en la enseñanza porque modela una computadora sencilla que utiliza la arquitectura de von Neumann, que tiene todas las características básicas de una computadora moderna. Puede ser programada con código máquina (aunque en lugar de usar un sistema binario, utiliza el decimal) o con código ensamblador.[2][3][4]

Arquitectura del sistema

El modelo LMC está basado en el concepto de un hombre pequeño encerrado en una habitación. En la habitación hay 100 cajas (memorias), numeradas del 0 al 99 y cada una puede contener una instrucción o dato de 3 dígitos (desde el 000 al 999). Además hay dos cajas al otro extremo etiquetadas ENTRADA y SALIDA que son utilizadas para recibir y enviar información.

En el centro de la habitación, existe una zona de trabajo que contiene una calculadora simple con dos funciones (suma y resta) denominada acumulador y un contador reprogramable denominado contador de programa. El Contador de Programa guarda la dirección de la próxima instrucción que el hombre pequeño va a realizar. Este contador de programa normalmente se incrementa en 1 después de que se ejecuta una instrucción, permitiéndole al hombre pequeño realizar su trabajo a lo largo del programa de manera secuencial.

Existen instrucciones de bifurcación que permiten realizar iteraciones (lazos) e incorporar al programa estructuras de programación condicionales. Colocando el contador de programa en una dirección de memoria no secuencial si se cumple una determinada condición (por lo general el valor almacenado en el acumulador es cero o positivo). Tal como establece la arquitectura de von Neumann, la memoria contiene tanto instrucciones como datos. Por lo tanto es preciso tener cuidado de detener el contador de programa antes de alcanzar una dirección de memoria que contenga datos o el hombrecillo intentará utilizarla como si fuera una instrucción. Para utilizar la LMC el usuario carga datos en las cajas y luego le indica al hombre pequeño que comience a trabajar, comenzando con la instrucción almacenada en la dirección de memoria (caja) cero. Restablecer el contador de Programa a cero hace que el programa comience nuevamente desde el principio.

Ciclo de ejecución

Para ejecutar un programa, el hombre pequeño realiza los siguientes pasos:

  1. Comprueba el contador de programa, que tiene un número de caja que contiene una instrucción de programa (por ejemplo, cero).
  2. Busca qué instrucción hay en la caja con ese número.
  3. Incrementa el contador de programa (de forma que contenga el número de caja de la siguiente instrucción).
  4. Decodifica la instrucción (esto incluye encontrar el número de la caja que contiene los datos con los que trabajará, por ejemplo, que diga que hay que obtener los datos de la caja 42).
  5. Recupera los datos de la caja con el número encontrado en el paso anterior (por ejemplo, almacena los datos de la caja 42 en el acumulador).
  6. Ejecuta la instrucción.
  7. Almacena los nuevos datos en la caja desde donde se recuperaron los datos antiguos.
  8. Repite el ciclo o para.

Comandos

Aunque el LMC sí refleja el funcionamiento real de los procesadores binarios, se eligió la simplicidad de los números decimales para minimizar la complejidad a los estudiantes, puesto que puede no resultar cómodo trabajar en un sistema binario o hexadecimal.

Instrucciones

Algunos simuladores LMC se programan utilizando directamente instrucciones numéricas de 3 dígitos y otros con códigos mnemotécnicos de 3 letras y etiquetas. En cualquier caso, el conjunto de instrucciones es deliberadamente muy limitado (normalmente unas diez instrucciones) para simplificar la comprensión. Cuando el LMC utiliza códigos mnemotécnicos y etiquetas, después, se convierten en instrucciones numéricas de 3 dígitos cuando se ensambla el programa. El primer dígito de una instrucción numérica representa el comando a ejecutar y los dos últimos dígitos representan la dirección de memoria de la caja correspondiente a este comando.

La tabla de abajo muestra un conjunto típico de instrucciones numéricas y los códigos mnemotécnicos equivalentes.

Instrucciones
Código numérico Código mnemotécnico Instrucción Descripción
1xx ADD ADD Suma el valor almacenado en la caja xx a cualquier valor que se encuentre actualmente en el acumulador (calculadora)
Nota: El contenido de la caja no cambia, y las acciones en el acumulador (calculadora) no están definidas para instrucciones de suma con resultados de más de 3 dígitos.
2xx SUB SUBTRACT Resta el valor almacenado en la caja xx de cualquier valor que se encuentre actualmente en el acumulador (calculadora).
Nota: El contenido de la caja no cambia, y las acciones en el acumulador no están definidas para instrucciones de resta con resultados negativos (pero, se establecerá un registro de estado negativo de forma que 8xx (BRP) se pueda utilizar correctamente).
3xx STA STORE Almacena el contenido del acumulador en la caja xx (destructivo).
Nota: El contenido del acumulador (calculadora) no se modifica (no destructivo), pero el contenido de la caja se sustituye independientemente de lo que hubiera antes (destructivo).
5xx LDA LOAD Carga el valor de la caja xx (no destructivo) y lo introduce en el acumulador (destructivo).
6xx BRA BRANCH (incondicional) Establece la dirección indicada (valor xx) en el contador de programa. Es decir, el valor xx será la siguiente instrucción ejecutada.
7xx BRZ BRANCH IF ZERO (condicional) Si el acumulador (calculadora) contiene el valor 000, establece el valor xx en el contador de programa. En caso contrario no hace nada.
Nota: Puesto que el programa se almacena en la memoria, todos los datos y las instrucciones del programa tienen el mismo formato de dirección/ubicación.
8xx BRP BRANCH IF POSITIVE (condicional) Si el acumulador (calculadora) es 0 o positivo, establece el valor xx en el contador de programa. En caso contrario no hace nada.
Nota: Puesto que el programa se almacena en la memoria, todos los datos y las instrucciones del programa tienen el mismo formato de dirección/ubicación.
901 INP INPUT Va a la ENTRADA, obtiene el valor que ha introducido el usuario y lo pone en el acumulador (calculadora).
Nota: Esto sobreescribe cualquier valor que se encuentre en el acumulador (destructivo)
902 OUT OUTPUT Copia el valor del acumulador (calculadora) en la SALIDA.
Nota: El contenido del acumulador no cambia (no destructivo).
000 HLT/COB HALT/COFFEE BREAK Deja de trabajar.
DAT DATA Esta es una instrucción de ensamblador que únicamente carga el valor en la siguiente caja disponible. DAT también se puede utilizar en conjunción con etiquetes para declarar variables. Por ejemplo, DAT 984 almacena el valor 984 en una caja, en la dirección de la instrucción DAT.

Ejemplos

Uso de códigos de instrucciones numéricas

Este programa de ejemplo se ha escrito usando códigos numéricos (las instrucciones 901,... 000). El programa pide dos números como ENTRADA y devuelve la resta como SALIDA. Obsérvese que la ejecución comienza en la posición 00 y acaba en la 07. Las desventajas de la programación con LMC con códigos de instrucción numéricos se verán después.

Caja Código numérico Operación Comentarios
00 901 ENTRADA → ACUMULADOR Introducir (INPUT) el primer número, en la calculadora (borra todo lo que había)
01 308 ACUMULADOR → MEMORIA[08] Almacena (STORE) el valor actual de la calculadora (se prepara para el siguiente paso...)
02 901 ENTRADA → ACUMULADOR Introduce (INPUT) el segundo número, en la calculadora (y borra el primer número)
03 309 ACUMULADOR → MEMORIA[09] Almacena (STORE) el valor actual de la calculadora (de nuevo, se prepara para el siguiente paso...)
04 508 MEMORIA[08] → ACUMULADOR (Ahora que los dos valores de entrada están almacenados en las cajas 08 y 09...)

Carga (LOAD) el primer valor, de nuevo, en la calculadora (y borra lo que había)

05 209 ACUMULADOR = ACUMULADOR - MEMORIA[09] Resta (SUBTRACT) el segundo número al valor actual de la calculadora (que era el primer número)
06 902 ACUMULADOR → SALIDA Devuelve (OUTPUT) el resultado de la calculadora como SALIDA
07 000 (no hace ninguna operación) Para (HALT) el LMC

Uso de códigos mnemotécnicos y etiquetas

El lenguaje ensamblador es un lenguaje de programación de bajo nivel que utiliza la mnemotécnia y etiquetas en lugar de códigos de instrucciones numéricas. Aunque el LMC utiliza un conjunto limitado de mnemotécnicos, la conveniencia de usar una regla mnemotécnica para cada instrucción del lenguaje ensamblador se hace evidente en el mismo programa que se muestra a continuación (el programador ya no tiene que acordarse de una serie de códigos numéricos anónimos y puede programar con un conjunto de códigos mnemotécnicos más fáciles de memorizar). Si la sentencia es una instrucción que implica una dirección de memoria (ya sea una instrucción de salto o datos que se tienen que cargar o guardar), entonces utiliza una etiqueta para nombrar esa dirección.

Este programa de ejemplo puede ser compilado y ejecutado en el simulador de LMC[5]​ disponible en el sitio web de la Universidad de York (Toronto, Canadá) o en la aplicación de escritorio escrita por Mike Coley.[6]​ Todos estos simuladores incluyen instrucciones completas y programas de ejemplo, un ensamblador para convertir el código ensamblador a código máquina, interfaces de control para ejecutar y supervisar los programas y una descripción paso a paso detallada de cada instrucción LMC.
INP
STA PRIMERO
INP
STA SEGUNDO
LDA PRIMERO
SUB SEGUNDO
OUT
HLT
PRIMERO DAT
SEGUNDO DAT

Etiquetas

Sin etiquetas el programador necesita calcular manualmente las cajas (direcciones de memoria) donde almacenar los datos.

En el ejemplo con código numéricos, si se añade una nueva instrucción antes de la instrucción HLT final, como resultado se moverá la instrucción HLT desde la caja 07 a la 08 (el etiquetado de direcciones del programa comienza en la posición 00). Supongamos que el usuario introduce 600 como primera entrada (en la instrucción 901 de la caja 00). La instrucción 308 (caja 01) hace que este valor se almacene en la caja 08, y sobreescribe la instrucción 000 (HLT) con el valor 600. La instrucción 600 significa saltar a la dirección (caja) 00 del programa, así, en lugar de pararse, el programa se queda atrapado en un bucle sin fin.

Para solucionar esta dificultad, la mayoría de los lenguajes ensambladores (incluyendo el LMC) combinan los códigos nemotécnicos con etiquetas. Una etiqueta no es más que una palabra que se utiliza para nombrar cualquier dirección de memoria donde se almacena una instrucción o un dato, o para referirse a esta dirección en una instrucción.

Cuando un programa se ensambla:

  • Una etiqueta a la izquierda de una instrucción se convierte en la dirección de memoria donde se almacena la instrucción o los datos. Por ejemplo, iniciobucle INP
  • Una etiqueta a la derecha de una instrucción toma el valor de la dirección de memoria antes mencionada. Por ejemplo, BRA iniciobucle
  • Una etiqueta combinada con una declaración DAT funciona como una variable, hace que los datos se almacenen en la dirección de memoria de la etiqueta. Por ejemplo, one DAT 1 o numero1 DAT

En el ejemplo de lenguaje ensamblador que utiliza mnemotécnia y etiquetas, si una nueva instrucción se inserta antes de la instrucción HLT final, entonces la ubicación de la dirección marcada con la etiqueta PRIMERO estará ahora en la posición de memoria 09 en lugar de la 08, y la primera instrucción STA se convertirá en 309 (STA 09) en lugar de 308 (STA 08) cuando se ensamble el programa.

Por lo tanto, las etiquetas se utilizan para:

  • Identificar una instrucción particular como destino de una instrucción de salto (BRANCH).
  • Identificar una ubicación de memoria como una variable con un nombre (utilizando DAT) y, opcionalmente, cargar determinados datos cuando se ensambla el programa para su uso posterior cuando se ejecute. Este uso no se hace evidente hasta que uno se da cuenta de que no hay ninguna otra forma de sumarle 1 a un contador: Se le podría pedir al usuario que introdujera el 1 al inicio (INPUT), pero es mejor cargarlo cuando se ensambla el programa usando one DAT 1)

Ejemplos

Este programa pide una ENTRADA al usuario, y hace una cuenta atrás hasta cero.

     INP
LOOP SUB ONE  // Etiqueta esta instrucción com LOOP y resta el valor de ONE al valor del acumulador
     OUT
     BRZ QUIT // Si el valor del acumulador es 0, salta a la dirección etiquetada QUIT
     BRA LOOP // Si el valor del acumulador no es 0, salta a la dirección etiquetada LOOP
QUIT HLT      // Etiqueta esta dirección como QUIT
ONE  DAT 1    // Almacena 1 en esta dirección de memoria, y la etiqueta ONE (declaración de variables)

Este programa pide una ENTRADA al usuario, calcula el cuadrado, muestra la respuesta y vuelve a repetir. La introducción de un cero finaliza el programa.
(Nota: una entrada que de un resultado superior a 999 producirá un error debido al límite de 3 dígitos del LMC)

START   LDA ZERO     // Inicializa la ejecución del programa múltiple
        STA RESULT
        STA COUNT
        INP          // Entrada proporcionada por el usuario
        BRZ END      // Salto del programa a END si entrada = 0
        STA VALUE    // Almacena la entrada como VALUE
LOOP    LDA RESULT   // Carga el resultado en RESULT
        ADD VALUE    // Suma la entrada VALUE a RESULT
        STA RESULT   // Almacena el nuevo resultado en RESULT
        LDA COUNT    // Carga la cuenta COUNT
        ADD ONE      // Suma ONE a la cuenta COUNT
        STA COUNT    // Almacena COUNT
        SUB VALUE    // Resta la entrada VALUE a COUNT
        BRZ ENDLOOP  // Si cero (VALUE suma RESULT VALUE veces) salta a ENDLOOP
        BRA LOOP     // Salta a LOOP para continuar sumando VALUE a RESULT
ENDLOOP LDA RESULT   // Carga RESULT
        OUT          // Devuelve RESULT
        BRA START    // Salta a START para comenzar y pedir otro VALUE
END     HLT          // Se para (¡Hemos introducido antes un cero!)
RESULT  DAT          // Resultado computado (por defecto 0)
COUNT   DAT          // Contador (por defecto 0)
ONE     DAT 1        // Constante con valor 1
VALUE   DAT          // Entrada proporcionada por el usuario, el valor que queremos al cuadrado (por defecto 0)
ZERO    DAT          // Constante con valor 0 (por defecto 0)

Nota: Si no hay datos después de una declaración DAT, entonces se almacena en la dirección de memoria el valor predeterminado 0.

Referencias

  1. «Little Man Computer». Universidad Estatal de Illinois. 1 de mayo de 2000. Archivado desde el original el 27 de febrero de 2009. Consultado el 8 de marzo de 2009. 
  2. Yurcik, W.; Osborne, H. (2001). "A crowd of Little Man Computers: Visual computer simulator teaching tools". Proceeding of the 2001 Winter Simulation Conference (Cat. No.01CH37304) 2. p. 1632. doi:10.1109/WSC.2001.977496. ISBN 0-7803-7307-3.
  3. Yurcik, W.; Brumbaugh, L. (2001). "A web-based little man computer simulator". Proceedings of the thirty-second SIGCSE technical symposium on Computer Science Education - SIGCSE '01. p. 204. doi:10.1145/364447.364585. ISBN 1581133294.
  4. Osborne, H.; Yurcik, W. (2002). "The educational range of visual simulations of the Little Man Computer architecture paradigm". 32nd Annual Frontiers in Education. pp. S4G–S19. doi:10.1109/FIE.2002.1158742. ISBN 0-7803-7444-4.
  5. Chen, Stephen Y.; Cudmore, William C. York University, ed. «The Little Man Computer». Consultado el 7 de octubre de 2010. 
  6. Coley, Mike. «The Little Man Computer». Consultado el 12 de abril de 2012. 

Enlaces externos

Simuladores