Simulador máquina Von Neumann

Inauguro la publicación en el blog con un post que habla sobre el simulador de la máquina de Von Neumann desarrollado por la Universidad de Oviedo.

Se trata de un simulador portable para sistemas operativos Windows que permite emular el funcionamiento de un computador con arquitectura Von Neumann.

Al ser una herramienta con interfaz gráfica (ver la imagen del post), podemos ver los registros que hay contenidos en la CPU, la memoria, las líneas de conexión entre estos elementos (buses), etc.

Captura de pantalla del Simulador máquina de Von Neumann

Captura de pantalla del Simulador máquina de Von Neumann

Así pues, ésta herramienta nos permite monitorizar:

  1. Los señales internos de la CPU y los valores que hay en los registros de la misma.
  2. Las líneas de transmisión de información (buses) del sistema.

Y entre otras cosas, el simulador nos permite configurar la memoria del sistema así como dispositivos de entrada y salida como teclado (input), pantalla (output) o luces (input y output).

Voy a obviar mucha información sobre este simulador y pasaré a comentar el código del primer ejercicio de la asignatura Estructura de Computadores II de los alumnos del grado de informática de la Escuela Politécnica Superior de la Universidad de Lleida.

El enunciado, a modo resumen requería implementar un programa con inicio en la posición de memoria 0400h y que realizara la siguiente operación:

 resultado[i] \;= \;2 \cdot (2 \cdot operando1[i] + operando2[i]) - operando3[i] \;\forall \;i \;\in \;[0,4]

Dados 4 vectores operando1, operando2, operando3 y resultado; con los siguientes valores respectivamente:

  • operando1 = [0001h, 0002h, 0003h, 0004h, 0005h]
  • operando2 = [0005h, 0004h, 0003h, 0002h, 0001h]
  • operando3 = [0002h, 0002h, 0002h, 0002h, 0002h]
  • resultado = [0001h, 0001h, 0001h, 0001h, 0001h]

Pues bien, una de las posibles soluciones a esta práctica es la que se muestra a continuación:

CONSTANTE1 EQU 05h

ORIGEN 400h
INICIO ini

.DATOS
operand01 VALOR 0001h, 0002h, 0003h, 0004h, 0005h
operand02 VALOR 0005h, 0004h, 0003h, 0002h, 0001h
operand03 VALOR 5 VECES 0002h
resultado VALOR 5 VECES 0001h

.CODIGO

ini:
      MOVL R0, CONSTANTE1
      MOVH R0, 00h

      MOVL R1, BYTEBAJO DIRECCION operando1
      MOVH R1, BYTEALTO DIRECCION operando1
      MOVL R2, BYTEBAJO DIRECCION operando2
      MOVH R2, BYTEALTO DIRECCION operando2
      MOVL R3, BYTEBAJO DIRECCION operando3
      MOVH R3, BYTEALTO DIRECCION operando3
      MOVL R4, BYTEBAJO DIRECCION resultado
      MOVH R4, BYTEALTO DIRECCION resultado

operar:
      MOV R5, [R1]
      MOV R6, [R2]
      ADD R5, R5, R5
      ADD R5, R5, R6
      ADD R5, R5, R5
      MOV R6, [R3]
      SUB R5, R5, R6
      MOV R6, R4
      MOV [R6], R5
      INC R1
      INC R2
      INC R3
      INC R4
      DEC R0
      BRNZ operar

final:
    JMP -1

FIN

Así pues, en la primera parte del código, veremos como R1, R2, R3 y R4 están apuntando a las posiciones de memoria de los primeros valores de los vectores operando1, operando2, operando3 y resultado respectivamente. Teniendo en cuenta que el programa empieza en la posición de memoria 0400h y que los 4 vectores tienen 5 elementos, antes de la etiqueta operar los valores de los registros mencionados serán:

  1. R1=400h
  2. R1=405h
  3. R1=40Ah
  4. R1=40Fh

De este modo, una vez dentro de la función (bucle) con etiqueta operar lo que hacemos es:

operar:
MOV R5, [R1]
MOV R6, [R2]

Cargamos el contenido de la dirección de memoria que apuntada por R1 y R2 en los registros R5 y R6 respectivamente. Por tanto, la primera vez que se ejecutan ambas sentencias, los valores de R5 y R6 serán 0001h y 0005h respectivamente.

En la siguiente porción de código, realizamos la operación que nos pide realizar el problema, para una iterador o [code]i[/code] concreto.

ADD R5, R5, R5
ADD R5, R5, R6
ADD R5, R5, R5
MOV R6, [R3]
SUB R5, R5, R6

Uno de los requisitos del problema, es almacenar el resultado de cada iteración en el vector resultado[i]. Para ello cargamos la dirección de memoria que tenemos almacenada en el registro R4 a R6, lo cual nos cargará en la primera iteración el valor 040Fh ; para luego almacenar el resultado de la operación almacenado en R5 en la dirección de memoria apuntada por R6, es decir [R6].

MOV R6, R4
MOV [R6], R5

Por último, tenemos que incrementar el iterador i, lo cual nos permitirá saltar al siguiente valor de los vectores. Para ello, incrementamos los registros R1 a R4. Por último, decrementaremos el registro R0, que contiene el valor hexadecimal 0005h , valor que se decrementaremos cada vez que hayamos finalizado una iteración. Hasta cuánto iteraremos? Pues bien, ejecutaremos el código que hay dentro de la función o etiqueta operacion mientras R0 no sea 0000h , lo cual nos va a permitir realizar 5 iteraciones (de 0005h a 0001h ambos incluidos).

INC R1
INC R2
INC R3
INC R4
DEC R0
BRNZ operar

Por último finalizamos el código una vez acabadas las iteraciones.

final:
    JMP -1

FIN
Posted in computer science, teaching

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>