ESPECIFICACIONES DEL PROCESADOR SIMUPROCELEMENTOS Memoria: Es el dispositivo que almacena toda la información del programa que se ejecuta, tanto datos como instrucciones. En realidad no es parte del procesador, sino que es un dispositivo anexo al que el procesador accede para ir leyendo las instrucciones y datos del programa. La capacidad de la memoria Simulada es de 4096 posiciones de 16 bits cada una: Desde 0 hasta 4095, o desde 000h hasta FFFh. Esta memoria es suficiente para ejecutar gran variedad de simples y complejos programas. El simulador trabaja con constantes y variables en binario y direcciones (posiciones de memoria) en hexadecimal. Registros Generales: Los registros generales del procesador se usan para almacenar información de uso rápido, ya que se accede a ellos a una velocidad mucho más alta que a la memoria. En ellos se pueden almacenar direcciones de memoria a las que se va a acceder con frecuencia a lo largo de la ejecución del programa, o directamente variables que se desean usar. Este Procesador consta de 3 registros de propósito general, AX, BX y CX cada uno con 16 bits de capacidad. Registros Apuntadores: Los registros apuntadores son los encargados de direccionar las distintas posiciones de memoria del sistema. En SimuProc nos enccontraremos con los siguientes: PC ó IP: Program Counter o Instruction Pointer; contiene la dirección de memoria de la próxima instrucción a ejecutar y es incrementado en cada nueva instrucción. MAR: Memory Address Register (Registro de Dirección de Memoria) es el registro en el que se almacena la dirección de memoria a la que se quiere acceder. MDR: Memory Data Register o Memory Buffer Register, es un registro intermedio en el que se almacenan los datos que se escriben o leen de memoria. En el caso de una lectura, se pone en el MAR la dirección y se activa la señal de leer, obteniendo en el MDR el dato buscado. En el caso de una escritura, se pone en el MAR la dirección y en el MDR el dato a escribir en memoria, después de activa la señal de escribir, de esta forma almacenamos en memoria el dato. IR: Instruction Register, en este registro se introduce la instrucción a ejecutar, después de haberla leído de memoria accediendo a ella mediante la dirección señalada en el PC; El contenido de este registro se puede dividir en código de operación (el código que señala la operación que se realizará) y operandos. Puede haber 2 operandos o sólo uno. Acá es donde se decodifica e interpreta la instrucción así: se descompone la instrucción leída de forma que se pueda saber cual es la operación que se desea realizar y cuales son los operandos, en su caso, o el desplazamiento en caso de que se trate de una instrucción de bifurcación... Registros de Pila: BP: Base Pointer, Puntero de base de la pila. El valor de por defecto es F80, aunque se puede cambiar desde un programa, asignándole otra dirección de memoria con la instrucción MOV. Digamos que se desea reservar más espacio para la pila haciendo que ésta comience desde la posición CF1, entonces se copia este dato en cualquier posición de memoria; supongamos que le elige la dirección 3B entonces se utilizará la instrucción MOV BP,3B y así BP será igual a CF1. Mientras se ejecuta el programa se puede visualizar en una barra de porcentaje el uso de la pila. SP: Stack Pointer, Puntero de la pila, indica qué próxima dirección de la pila está disponible, es decir, apunta a la cima de la pila. Este valor se cambia automáticamente cuando se usan las instrucciones PUSH ó POP. Registros de Control (Flags): Estos registros se usan para poder controlar el comportamiento de un programa los cuales se activan después de cada operación, según sea el resultado de la instrucción ejecutada. Estos flags se usan principalmente en instrucciones de bifurcación. Zero flag: Se vuelve 1 si el resultado de la última operación es cero (Z=1). Negative ó Sign flag: Se vuelve 1 (N=1)si el resultado de la última operación es igual a un numero negativo. Carry flag: Se activa (C=1) cuando la operación realizada ha producido un acarreo. Overflow flag: se activa (O=1) cuando la operación produjo desbordamiento (overflow) , es decir, el resultado ocupaba más de los 16 bits que caben en un registro. ALU (Arithmetic Logic Unit) - (Unidad Arimética y Lógica): Es donde el procesador realiza las operaciones matemáticas, (suma, resta, multiplicación...) y las operaciones lógicas (AND, OR, desplazamiento de bits...). UTILIDADES Editor Interno: Herramienta para facilitar la escritura de programas: Tiene resaltado de sintaxis, soporte de Deshacer, Rehacer, Desplazamiento o tabulación de código seleccionado (presionando ctrl. Shit I ó U), marcadores (presionando Ctrl Shit. 1-9 para marcar y ctrl. 1-9 para ir al marcador), y otras opciones configurables. Editor de Memoria: Se usa para inicializar las variables y/o constantes del programa en ciertas posiciones de memoria una vez realizado el programa. También se pueden modificar posiciones de memoria en cualquier momento, ya sea antes ó durante la ejecución de un programa en caso de que se necesite, ya sea para depurar éste modificando variables, o las mismas instrucciones con sus parámetros. Dispositivos virtuales: Cada computador real utiliza dispositivos periféricos de alguna clase para conectarse con el mundo exterior. SimuProc posee unos dispositivos de E/S, virtuales que están conectados a unos puertos a los que se puede acceders con las instrucciones In y Out dependiendo del tipo de dispositivo. • Puerto 1: Teclado y Pantalla. Usado solo Para pedirle al usuario un numero de 32 bits, o para imprimir uno en pantalla, ej: IN AX,1 ;pide al usuario un número IEEE 754. Ej: OUT 1,AX ; escribe en pantalla el número de 32 bits formado por BX y AX. • Puerto 8 : Reloj. Lee los segundos del sistema, retorna un numero en binario (entre 0 y 59) al registro especificado. (Sirve para generar números aleatorios) • Puerto 9: Switches. Este dispositivo, consiste de 16 switches en fila enumerados de 0 a 15.Cualquier switch puede ser encendido resultando un “1” lógico correspondiente al bit del switch. • Puerto 13: PC-Speaker. Genera sonidos a través del altavoz de tu PC. Para generar un Sonido necesitas dar la frecuencia y la duración en milisegundos. La frecuencia debe ser entre 7Hz y 32767Hz La frecuencia es leída del registro especificado en la instrucción, y la duración es leída del registro BX. Ejemplo: Supongamos que AX = 101000101000 y BX = 111110100; OUT 13,AX ; produce un sonido de 2600Hz durante 500 ms. Para averiguar los Hz de algunas notas se puede usar la siguiente formula: Frecuencia, en Hertz = 440 * 2^[(octavo-4) + (nota/12)] Donde las notas comienzan así: A=0 A#=1 B=2 C=3 C#=4 D=5 D#=6 E=7 F=8 F#=9 G=10 G#=11 siendo: C=Do D=Re E=Mi F=Fa G=Sol A=La B=Si Por ejemplo: C6 => 440 * 2^[(6-4) + 3/12)] = 2093 Hz, ó casi 2.1 kHz Conversor de Bases: Permite la conversión de una base a cualquier otra. Soporta desde base 2 a base 36. También posee conversión para números de punto flotante a IEEE 754 y viceversa. Estadísticas: El simulador muestra constantemente las estadísticas del programa en ejecución, tales como número de instrucciones ejecutadas, clase de instrucción y la velocidad de procesamiento, etc. Vigilante de Memoria: Con el vigilante de memoria se pueden observar el valor de las variables en las posiciones de memoria. Dispone de un historial que muestra los últimos 5 valores de las posiciones vigiladas. Velocidad de Simulación: Puede ser cambiada en cualquier momento y se puede apagar la animación para una ejecución mucho más rápida. Es posible seguir el acceso en memoria de las instrucciones y/o variables a medida que se ejecuta la simulación Resolución del monitor: Al ejecutarse el Simulador este chequea que Windows este usando fuentes pequeñas y que la resolución sea como mínimo de 800x600; en caso contrario sacará una ventana de dialogo para cambiarla si el usuario desea. Archivos SMP: El Simulador registra los archivos de tipo .SMP para que se puedan abrir mediante un doble clic desde el explorador de Windows. Barras de Porcentaje: Muestran el porcentaje de uso de la memoria simulada y el porcentaje de uso del espacio reservado para la pila en cada momento. Registros de control (flags): Se les puede dar un doble clic para hacer un cambio forzado de los mismos en caso de que se necesite depurar su programa. Si se da clic con el botón derecho del ratón saldrá un menú para seleccionar que flag quiere activar/desactivar. Carga de programas: Se pueden entrar las instrucciones manualmente por la interfaz del programa y se pueden abrir los siguientes tipos de archivos: SMP: que son los creados por este mismo cuando se salvan. TXT o ASM: que son compatibles con la versión anterior de este simulador. Pila: La pila es simplemente un conjunto de datos que se almacenan en una zona de memoria, generalmente al final, y en la cual los datos se guardan con la estructura LIFO ( Last In, First Out). La Pila es un buffer usualmente implementado como un bloque de n bytes o words consecutivos. En este simulador cada posición de memoria es de 16 bits Usos para la pila: Ya sea para almacenar datos, para llevar control del programa, la pila se usa para pasar variables entre funciones y para almacenar variables locales. El programador es el responsable de reservar el espacio apropiado para la pila (ya explicado anteriormente). Un problema con las pilas es que el programador las puede hacer muy pequeñas y puede que ocurra un stack overflow o desbordamiento de pila si se esta intentando usar la instrucción PUSH para enviar algo cuando ya la pila esta llena; o stack underflow si se usa la instrucción POP estando la pila vacía. Por cada PUSH debe de haber luego un POP. Cuando un programa o función termina su ejecución la pila debe quedar como estaba antes de que este se ejecutara; en caso contrario habrá errores. INSTRUCCIONES SOPORTADAS Con las instrucciones que soporta este simulador se pueden escribir una gran cantidad de programas para resolver muchos problemas diferentes. Su sintaxis será la siguiente: XX - INST [par1] [par2] Donde XX es el Código de la instrucción, INST es la instrucción y [par1] [par2] son los parámetros si éstos existen. La versión 1.4.3.0 soporta las siguientes instrucciones: Sintaxis Descripción 01 - LDA [mem] Carga en AX el contenido de la dirección de memoria especificada. Si en (1F)=10111, después de ejecutada la instrucción LDA 1F se obtendría que AX=10111. Es equivalente a usar la instrucción MOV AX,1F. Esta instrucción se encuentra disponible para tener compatibilidad con versiones anteriores. Es mejor usar MOV. 02 - STA [mem] Guarda el contenido de AX en la dirección de memoria especificada. Si tenemos el valor 1010110 en el registro AX y se desea almacenarlo en la posición de memoria 3C, la instrucción es STA 3C. Es equivalente a usar la instrucción MOV 3C,AX Esta instrucción se encuentra disponible para tener compatibilidad con versiones anteriores. Es mejor usar MOV debido a que si se desea pasar algún dato de una dirección de memoria a otra usando LDA y STA se necesitarían dos instrucciones: LDA mem1 y luego STA mem2, mientras que con MOV será así: MOV mem2,mem1 03 - XAB Intercambia los valores de los registros AX y BX instrucción no necesita parámetros. 04 - CLA Pone a cero AX (AX = 0) 06 - PUSH [registro] Envía el valor del registro especificado a la pila 07 - POP [registro] Extrae de la Pila el último valor llevado por PUSH (indicado por el registro SP) y lo almacena en el registro especificado. Esta Sintaxis Descripción 08 - INC [dest] Incrementa en 1 el destino especificado, el parámetro puede ser una dirección de memoria o un registro. Si en la posición de memoria EB esta el valor 1001, al ejecutar INC EB se obtiene que ahora el valor de EB es 1010. 09 - DEC [dest] Decrementa en 1 el destino especificado. Si el destino da como resultado cero el flag Z se pone a 1 (Z = 1). 10 - MOV [dest,orig] Copia el valor almacenado en el origen al destino. El destino y/o origen pueden ser registros o direcciones de memoria o combinación de estos. Para copiar lo que esta en la posición de memoria 12E a la posición D2 se usa la instrucción MOV D2,12E 11 – AND [dest,orig] Producto lógico entre los dos operandos escribiendo el resultado en el destino. Los parámetros pueden ser direcciones de memoria o Registros. Si AX=1001101 y la posición (3F)=11011, al ejecutar la instrucción AND AX,3F se obtiene AX=1001. Observe que se dejan los bits en común que tienen los dos números. 12 – NOT [destino] NO lógico, invierte los bits del operando formando el complemento del primero. Si en AX=10011, al ejecutar NOT AX se obtiene AX=1111111111101100 13 – OR [dest,orig] Suma lógica entre los operandos escribiendo el resultado en el destino. Si en (3A)=1001101 y en (3B)=11011, al ejecutar la instrucción OR 3A,3B se obtiene en (3A)=1011111. 14 – XOR [dest,orig] Suma exclusiva entre los operandos escribiendo el resultado en el destino. Si en (3A)=1001101 y en (3B)=11011, al ejecutar la instrucción XOR 3A,3B se obtiene en (3A)=1010110. 15 – ROL [dest,veces] Rota los bits a la izquierda las veces especificadas (en decimal), los bits que salen por la izquierda re-entran por la derecha. En el flag del Carry (C) queda el último bit rotado. Si en (7E)= 101110, al ejecutar... se obtiene en 7E y en C ROL 7E,2 10111000 0 ROL 7E,7 1011100000000 0 ROL 7E,13 1100000000000101 1 16 – ROR [dest,veces] Rota los bits a la derecha las veces especificadas (en decimal), los bits que salen por la derecha re-entran por la izquierda. El flag C guarda el último bit rotado. 17 – SHL [dest,veces] Desplaza los bits a la izquierda el número de veces especificado (en decimal), agregando ceros a la derecha, el Carry Flag guarda último bit desplazado 18 – SHR [dest,veces] Desplaza los bits a la derecha el número de veces especificado (en decimal), agregando ceros a la izquierda, el flag C guarda último bit desplazado. Si en (1A)=101110 Sintaxis 20 - ADD [mem] 21 - SUB [mem] 22 - MUL [mem] Descripción Al Ejecutar... se obtiene en 1A SHR 1A,2 SHR 1A,6 SHR 1A,11 1011 0 0 y en C 1 1 0 Suma AX con el dato de la posición de memoria indicada. AX = AX + (memoria). Resta a AX el dato de la posición de memoria indicada. AX = AX - (memoria). Multiplica: AX = AX * (memoria). Si el número resultante supera su longitud en binario de 16 bits, este resultado se parte almacenando los bits más significativos en el registro BX. Si el resultado de una operación es, pr ejemplo,101101000111100010111 (21 bits), los registros quedarían así: A = 1000111100010111 (los últimos 16bits) B = 10110 (los primeros Bits) También se activa el flag Overflow, para indicar que en la última operación sucedió esto. 23 - DIV [mem] Divide: AX = AX / (memoria), BX= módulo o residuo. 24 - CLN 25 - CLC Limpia el Negative Flag. N = 0 Limpia el flag Carry (C = 0). 26 - STC Pone a uno el flag Carry (C = 1). 27 - CMC Niega el flag Carry Flag (C = C'). 29 - LOOP [mem] Decrementa CX y va a la Pos de memoria si CX no es cero 30 - JMP [mem] Salto incondicional. PC = dirección de memoria donde está la siguiente instrucción a ejecutar. 31 - JEQ [mem] Salta si el flag Z es uno (Z = 1, PC = contenido de la memoria). 32 - CMP [mem] Compara AX con [mem], si AX es mayor, Z=0 N=0, si es igual Z=1 N=0, si es menor Z=0 N=1. Si AX=10110 y en (4G)=1100, al ejecutar la instrucción CMP 4G se obtine que como el número almacenado en AX es mayor entonces: Z=0 y N=0 33 - JME [mem] Salta si el flag N es uno (N = 1, PC = contenido de la memoria). Al ejecutar, por ejemplo, la instrucción JME 3F inmediatamente después de ejecutar la instrucción del Sintaxis Descripción ejemplo anterior de la instrucción 32, se verifica el flag N, y como en este caso se encuentra en 0 (porque el número no es menor) entonces no se realiza dicho Salto a 3F porque el valor de PC no se modifica, el programa sigue su ejecución. 34 - JMA [mem] Salta si los flags Z y N son cero (Z = 0 y N = 0, PC = contenido de memoria). Siguiendo con el ejemplo de la instrucción 32, al ejecutar seguidamente JMA G5 se verifican los flags N y Z, y como en este caso los dos son 0 (porque el numero es menor) entonces se realiza un salto a G5, ya que el valor de PC se modifica, y el programa sigue su ejecución. 35 - JC [mem] Salta si el flag C está a uno (C = 1, PC = contenido de memoria). 36 - JNC [mem] Salta si el flag C está a cero (C = 0, PC = contenido de memoria). 37 - JO [mem] Salta si el flag O está a uno (O = 1, PC = contenido de memoria). 38 - JNO [mem] Salta si el flag O está a cero (O = 0, PC = contenido de memoria). 39 - JNE [mem] Salta si el flag Z es cero (Z = 0, PC = contenido de memoria). 40 - LDT Lee un valor del teclado y lo lleva al registro AX Esta instrucción es para comunicarse con el usuario, pidiéndole que entre un dato. Se puede colocar una descripción del dato que pide, que se mostrará en tiempo de ejecución. 41 - EAP Escribe en pantalla el contenido del registro AX. Esta instrucción también es para comunicarse con el usuario. Se puede colocar una descripción del dato que se entrega, este se mostrará en tiempo de ejecución. 42 - MSG 50 - LDB [mem] Muestra un mensaje en pantalla. Ej: MSG "Hola Mundo !!" Se carga en AX el dato almacenado en la dirección [mem] + BX Si BX=1100 y (2B)=3A; LDB 1F carga 3A en AX. Aclaración: 1100=C; 1F+C=2B 51 - STB [mem] Guarda el contenido de AX en la dirección [mem] + BX. Si BX=101 ; STB 3A guarda AX en 3F 55 – LDF [mem] Carga en BX y AX un número de 32 bits (IEEE) que está almacenado en la dir [mem] y mem+1. En BX quedan los Sintaxis Descripción dígitos más significativos. Ej: Supongamos que el número 01000010110010001000000000000000 está cargado en memoria del siguiente modo: 02A = 0100001011001000 (Los MSB’s) 02B = 1000000000000000 (Los LSB’s) Un LDF 2A dejaría el siguiente resultado: 56 – STF [mem] 60 – ADDF [mem] 61 - SUBF [mem] 62 - MULF [mem] 63 - DIVF [mem] 64 - ITOF 65 - FTOI 80-IN registro,puerto 81-OUT BX = 0100001011001000 AX = 1000000000000000 -------------------------Nota: Para pedirle al usuario o mostrar estos números IEEE 754 en pantalla, usar puerto 1, con las instrucciones IN AX,1 y OUT 1,AX Guarda en [mem] y mem+1 el contenido de BX y AX. Ej: Si AX y BX tienen los mismos valores del ejemplo anterior, un STF 2A deja la memoria con el valor inicial del ejemplo anterior. Suma números de 32 bits: En BX y AX queda el resultado de la suma de estos mas el contenido de [mem] y mem+1. Estos números IEEE 754 pueden ser de punto flotante, o enteros desde -2147483647 hasta 2147483647 Si en cualquier operación aritmética se sobrepasa este valor, se activa el Overflow flag. Resta un número de 32 bits: BX y AX = BX y AX - [mem] y [mem+1]. Esta instrucción se puede utilizar como un CMP para números de 32 bits. Multiplicación: BX y AX = BX y AX * [mem]y [mem+1] Si el resultado es > 2147483647, Resultado = 2147483647 y Overflow Flag = 1 División: BX y AX = BX y AX / [mem]y [mem+1], en CX queda el residuo de la división en entero de 16 bits . Conversión de Entero a Real: Convierte un número entero (16bits) almacenado en AX al mismo número pero representado en Real IEEE754(32bits), el Resultado de la conversión queda en BX (MSB’s) y AX. Los registros de control cambian de acuerdo al número convertido: "Z" si el número es cero, "N" si el número es negativo. Conversión de Real a Entero: Convierte un número Real (32bits) a su equivalente en entero BX y AX en un entero (16bits), el Resultado queda en AX. Los registros de control cambian de acuerdo al número convertido: "Z" si el número es cero, "N" si el número es negativo, "O" si el numero real es mayor de 65535. Lleva al Registro el valor retornado por el puerto especificado. Ej: IN AX,8; lleva a AX el valor retornado por el puerto 8 (Reloj: los segundos del sistema). Escribe en el puerto especificado, el valor del registro. Sintaxis Descripción puerto,registro 90 - NOP Esta operación no hace nada. 99 - HLT Termina el programa. Todo programa lleva esta instrucción para indicarle al simulador que el programa ha terminado su ejecución. Nota: Generalmente las instrucciones de salto condicional 31, 33, 34 y 39 se utilizan inmediatamente después de usar la instrucción 32 - CMP