Arquitectura-de-Computadoras

[![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](https://github.com/Fabian-Martinez-Rincon/Arquitectura-de-Computadoras) [![GitHub stars](https://img.shields.io/github/stars/Fabian-Martinez-Rincon/Arquitectura-de-Computadoras)](https://github.com/FabianMartinez1234567/Arquitectura-de-Computadoras/stargazers/) --- ---

[!IMPORTANT]
Si encuentran algun link roto o tienen alguna duda, no duden en decirme por mail fabianmartinezrincon.123@gmail.com

Literal Estan todas las practicas resueltas y corregidas


Final (Mas abajo estan las practicas)

Link de donde me mire todas las clases Drive

Esto ya es lo ultimo para el final (Me queda este y el de concurrente y termino el Analista Programador Universitario). A meterle!!!

</div>

@carolina

Parametros e Interrupciones

1) Que métodos como pasaje de parametros podemos utilizar en una computadora? **Via registros:** Para pasar los parametros se usan los registros del procesador. Su principal limitación son los registros disponibles, es importante documentar cuales son los registros que estamos usando para evitar conflictos **Via Memoria** Los parametros se almacenan en un area difinida en la memoria RAM, es util cuando se deben pasar grandes cantidades de datos, pero es dificil de estandarizar. **Via PILA/STACK** Los parametros se colocan en la pila. Es el metodo mas utilizado, no depende ni de la memoria ni de los registros, hay que saber bien como utilizarlo ya que la pila es usada tanto por el sistema como por los programas del usuario. > Tambien puede tocar la siguiente pregunta: **Explique los métodos de pasaje de argumentos a procedimientos o funciones.**
2) Explique características y tratamiento de interrupciones múltiples. Las interrupciones multiples es cuando se reciben varias interrupciones al mismo tiempo. Son 3 caracteristicas **Prioridad de interrupciones:** Las interrupciones suelen tener una prioridad. Esto permite que el sistema decidir cual interrupcion debe manejar primero en caso de que ocurran multiples interrupciones. **Mascara de Interrupciones**: Algunos sistemas permiten desactivar temporalmente interrupciones (GENERALMENTE LAS DE MENOR PRIORIDAD) Utilizando las mascaras de interrupciones, esto ayuda a que las interrupciones de mayor prioridad no sean interrumpidad con las de mayor prioridad. Gerarquia de interrupciones: Enmascarables y no Enmascarables, Enmascarables pueden ser ignoradas (de baja prioridad) y las no Enmascarables no se pueden ignorar y son de alta prioridad **Nivel de anidación:** El sistema debe ser capa de manejar nivel de anidación. Si esta atendiendo una interrupcion y ocurre otra de mayor prioridad la interrupcion actual se suspende temporalmente, el sistema atiende la nueva interrupcion y al finalizar regresan para continuar con la interrupcion inicial. - Tratamiento: Se puede atender una interrupcion e inhabilitar a las demas con el uso de mascaras de interrupciones, de esta manera las interrupciones se maneja de forma secuencial. (Esto no me quedo claro 😕) - Tambien Es posible asignar prioridades a las interrupciones. Dependiendo del nivel de prioridad el sistema debe respetar su atención. - Si se esta manejado una interrupcion de menor prioridad y llega una de mayor prioridad se debe atender primero la de mayor prioridad. Una vez finalizada el procesador retoma la atención de la interrupcion previa.
3) Describir el mecanismo de interrupciones - 1) **Generar la interrupción**: Un disposito del sistema detecta un evento que requiere atención, por lo que se genera una señal de interrupción. - 2) **Interrupcion del procesador**: Cuando se genera una interrupción, el procesador suspende temporalmente su ejecución - 3) **Guardado de contexto**: Antes de manejar la interrupción el procesador guarda el estado actual del programa en ejecución, el contador de programa, registros y otros datos relevantes. - 4) **Rutina de manejo de interrupciones**: El controlador de interrupciones (PIC) determina cual es la interrupción y proporciona un puntero al procesador para buscar en la tabla de vectores la dirección en donde se encuentra la rutina de la interrupción. - 5) **Ejecución de la rutina de manejo**: El procesador comienza a ejecutar la rutina de manejo de interrupcion que corresponde, una vez finalizada la rutina el control es devuelto al punto del programa en donde se detuvo inicialmente. - 6) **Restauración del estado/contexto**: Despues de que se maneja la interrupción el procesador restaura el estado previo/guardado (Los registros y la dirección del programa (PC)), permitiendo que el programa restaure su estado original/inicial antes de que ocurra la interrupción. - 7) **Continuación de la ejecución**: Con el contexto restaurado, el programa original continuo su ejecución en el punto en donde se interrumpio
4) Describa como se realiza el reconocimiento de interrupciones vectorizadas mediante el pic. - Se genera una interrupción de un dispositivo externo o una señal de sofware, el pic recibe esa interrupción y la clasifica segun la prioridad que tenga, le avisa al procesador/CPU que hay una interrupción que tiene que se atendida, por la linea (IntR). - La CPU al finalizar la instrucción actual, responde al PIC que acepta la interrupción por la linea (INTA), Solicitando el puntero para acceder a la tabla de vectores. - El PIC le manda al puntero que corresponde a esa interrupción y la CPU lo usa para acceder a la tabla de interrupciones que tiene la dirección donde se encuentra la rutina de servicio de esa interrupción. - La CPU guarda su contexto actual (Contador de programa, registros, etc). Ejecuta la rutina del manejo de la interrupción y una vez finalizada, se le manda un señal al PIC de fin de interrupción (EOI) el PIC actualiza sus registros y puede anteder otras interrupciones. - La CPU restaura el contexto previo que tenia antes de anteder a la interrupcion y continua la ejecución
5) Cual son las diferencias entre la terminación de una subrutina y un gestor de interrupciones? 1) **Formas de finalización** - **Subritina**: finalizan con la instrucción de retorno RET - **Gestor de interrupciones**: Finaliza con la instrucción IRET 2) **Contexto de finalización:** - **Subrutina**: El contexto (Dirección de retorno, en algunos casos registros). Es gestionado por el programador y almacenado en la pila antes de la llamada a la subrutina. Al finalizar Se restaura manualmente desde la pila para volver al programa principal. - **Gestión de interrupciones:** El contexto completo del programa interrumpido (contador del programa, registros, etc) es automaticamente guardado y restaurado por el hardware al inicio y al final del gestor de interrupciones respectivamente. 3) **Continuación del flujo de la interrupción:** - **Subrutina**: Al retornar el programa principal continua su ejecución en la linea posterior a la instrucción de llamada. - **El gestor de interrupciones**: Una vez restaurado el contexto, la CPU reanuda automaticamente la ejecución del programa interrumpido desde el punto exacto en donde ocurrio la interrupción.
6) Esquematice y describa la estructura interna de un PIC.
![image](https://github.com/user-attachments/assets/3dadd7b0-cbb4-485b-ba64-dff871d13c32)
Estructura interna del PIC: El pic esta compuesto por un conjunto de registros. - EOI: Fin de interrupción - IMR: Mascara de interrupciones, Permite habilitar o deshabilitar ciertas interrupciones - IRR: Petición de interrupción, identifica que interrupción tiene una solicitud de petición para ser antendida. - ISR: Interrupción de servicio, indica cual es la interrupción que esta siendo atendida. - INT0..INT7: Registros relacionados con el vector de interrupciones

Tema Segmentación de Cause

1) A que se entiende por segmentación de cause (pipeline) Es la forma de organizar el hardware de la CPU para realizar mas de una operacion al mismo tiempo. Divide el proceso de ejecución de las instrucciones en etapas, permitiendo que se ejecuten de manera simultanea. ![segmentación](https://www.researchgate.net/profile/Leandro-Zambrano/publication/347483834/figure/fig5/AS:970292671291393@1608347208263/Comportamiento-en-el-tiempo-del-patron-segmentacion-de-cauce.ppm)
2) Cual es el rendimiento de segmentación de cause El rendimiento es la mejora de eficiencia del procesador al ejecutar varias interrupciones al mismo tiempo, dividiendo el proceso en varias etapas. Cada etapa trabaja en una parte diferente de una instrucción, lo que permite que varias instrucción se ejecuten de manera concurrente. Esto reduce el nro de ciclos de reloj necesarios para ejecutar instrucciones y aumentar el rendimiento. Sin enbargo existen riesgos como la dependencia de datos o saltos condicionales que pueden interrumpir el flujo y reducir la eficiencia. El rendimiento mejora cuando el procesador maneja bien estos riesgos, pudiendo manejar mas interrupciones en menos tiempo. > Se podria consultar
3) Describa el problema y posibles soluciones ante el riego por transferencia de control de programa **Problema**: Los riesgos por transferencia de control ocurren cuando el flujo del programa se ve alterado por las instrucciones de salto (Condicionales o incondicionales). Esto genera insertidumbre sobre que instrucción se tiene que seguir. Si ya se cargaron instrucciones incorrectas, debe descartarse lo que causa desperdicios de ciclos y penalización de rendimiento, **Posibles soluciones:** ### **Tecnicas de Software** **Salto retardado:** En la tecnica del salto retardado, el compilador reorganiza las instrucciones para que siempre alla algo que ejecutar despues del salto. Si no es posible agrega la instrucción NOP ### **Tecnicas de hardware** **Detención del cause:** Cuando se encuentra una interrupción de salto el procesador detiene temporalmente la ejecución hasta que se resuelva si se toma o no el salto. Esto evita que se ejecuten instrucciones incorrectas pero genera un retraso en el flujo de instrucciones **Adelantar la resolución de los saltos a la etapa de codificación**. En la etapa de codificación se identifica si la instrucción corresponde a un salto, la condición del salto se evalua mediante un restador y la dirección de destino de salto se calcula usando un sumador. Esto se debe a la toma de desiciones sobre el flujo de ejecución. **Predicción de salto:** El procesador intenta predecir si el salto sera tomado o no, para seguir ejecutando instrucciones mientras se confirma la condición del salto. Hay dos tipos de predicciones, estan las estaticas y las dinamicas - **Estaticas:** La predicción es fija, por ejemplo siempre se decide si se toman los saltos o no se toman - **Dinamica:** Se basa en el historial de ejecuciones anteriores de la misma instrucción de salto. Ejemplo: Tabla de historias de salto o buffer de destino (Branch Target Buffer)
4) Ventajas de la segmentación de Cause - 1) **Mejora el rendimiento:** La ejecución en paralelo acelera la velocidad de la ejecución de las instrucciones. - 2) **Aprovechamiento de recurso:** mientras una unidad de ejecución realiza una operación, las etapas anteriores y posteriores pueden estar ocupadas con otras instrucciones, permitiendo un uso mas completo de las unidades funcionales. - 3) **Mayor paralelismo:** Como varias instrucciones se ejecutan al mismo tiempo, la segmentación de Causa aumenta el nivel de paralelismo a nivel de instrucciones en el procesador. - 4) **Reducción del ciclo de reloj por instrucción:** Reduce el tiempo necesario para ejecutar una instrucción completa al dividirla en etapas mas pequeñas. - 5) **Mejora de la predicción de salto:** Tecnica que usa el procesador para anticipar si una instrucción de salto condicional se va a tomar o no, antes de que se evalue dicha condición. Esto ayuda a que el procesador siga trabajando sin detenerse mientras espera esa respuesta, evitante retrasos en el flujo de ejecución del programa.
6) Describa la dependencia de datos que puede afectar un cause segmentado 1) **RAW:** Una instrucción necesita leer que aun no ha sido escrita por una instrucción. 2) **WAW:** Dos instrucciones intantan escribir en el mismo lugar, pero deben hacerlo en orden distintos. 3) **WAR:** Una instrucción quiere escribir en un dato que otra esta leyendo.
7) Describa 3 motivos de retardo de cause en la segmentación de cause - 1) **Dependencia de datos:** Cuando una instrucción depende del resultado de la instrucción anterior que todavia no ha completado su etapa de ejecución. Tipos: RAW, WAW, WAR - 2) **Dependencias Estructurales:** Cuando dos o mas instrucciones compiten por el mismo recurso en una etapa especifica del cause. - 3) **Dependencia de Control (Saltos):** Ocurre cuando hay instrucciones de salto y el procesador no sabe que instrucción ejecutar hasta que no termina de evaluar la condición de salto. Esto podria insterrumpir el flujo del cause porque el procesador debe esperar el resultado de la condición para poder seguir. 7.2) ¿Que retardo produce cada una? > NO SABEMOS QUE RETARDO EN CUANTO A TIMPO | SIN CONTESTAR

Taxonomia Flynn

1) Describa las 4 variantes de arquitectura de la Taxonomia Flynn ![TaxonomiaFlynn](https://www.filosofias.es/wiki/lib/exe/fetch.php/a2/2/flynns-taxonomy-of-computer-architectures.png) Las 4 principales variantes de taxonomia flynn son: - 1) **SISD** (Single Instruction Single Data): Una sola unidad de procesamiento que ejecuta una secuencia de instrucciones, opera sobre un unico conjunto de datos en cada ciclo de reloj - 2) **SIMD** (Single Instruction Multiple Data) Una unica instrucción se aplica simultaneamente a multiples conjuntos de datos. Esto permite que varias unidades de procesamiento ejecutan la misma operación en paralelo sobre diferentes datos al mismo tiempo. - 3) **MISD** (Multiple Instruction Single Data): Multiples secuencias de instrucciones se ejecutan en paralelo en un solo conjunto de datos. - 4) **MIMD** (Multiple Instruction Multiple Data): Multiples unidades de procesamientos que ejecutan diferentes instrucciones sobre diferentes conjuntos de datos al mismo tiempo.
2) Describa las características que diferencian un SMP con respecto a los Clusters/ Compare los sistemas SMP y Clusters **Los SMP** se caracterizan por su arquitectura de **memoria compartida**, donde multiples procesadores comparten el mismo espacio de memoria y recursos, esto permite que todos los procesadores accedan a la memoria y a los recursos de manera igualitaria, la comunicación entre los procesadores es directa a traves de la memoria compartida, facilitando el intercambio de datos. **La ventajas** de los SMP es que son mas faciles de configurar, necesitan menos espacio fisico, necesitan menos energia y son plataformas estables y bien establecidas. ![SMP](https://iesbidaju.wordpress.com/wp-content/uploads/2016/05/smp_01.gif) **Los Cluster** estan compuestos por **nodos independietes** interconectados por una red, cada uno tiene su memoria y recurso, la comunicación se comunica mediante la red lo que puede generar latencia. Los Cluster ofrecen escalabilidad horizontal al permitir añadir mas nodos para aumentar la capacidad de procesamiento. ![Clusters](https://adictosaltrabajo.com/wp-content/uploads/tutorial-data/MySQLCluster/MySQLCluster_img1.png)
3) Que son los MIMD de la taxonomia Flynn **MIMD:** Multiples unidades de procesamientos que ejecutan diferentes instrucciones sobre diferentes conjuntos de datos al mismo tiempo. FIN

Procesadores super escalares y Super segmentado

1) Que caracteristicas tienen los procesadores superEscalares - **1. Captación simultánea de múltiples instrucciones**: Se buscan varias instrucciones al mismo tiempo para mejorar el rendimiento mediante el paralelismo. - **2. Gestión de dependencias de datos:** Se usan técnicas como el renombre de registros para evitar conflictos entre instrucciones que dependen de resultados previos. - **3. Ejecución paralela de múltiples instrucciones:** Se inician múltiples instrucciones a la vez, usando diferentes unidades funcionales para ejecutarlas simultáneamente. - **4. Recursos adecuados para ejecución en paralelo:** Tienen múltiples unidades de ejecución, para manejar múltiples instrucciones en paralelo. - **5. Entrega de resultados en orden:** Aunque las instrucciones se ejecutan fuera de orden, los resultados se entregan en el orden correcto para mantener la coherencia del programa.
2) Compare las politicas de emisión de instrucciones Políticas: - **1. Emisión y finalización en orden**: Las instrucciones se emiten y ejecutan en el mismo orden en que aparecen en el programa. Si una instrucción no puede ejecutarse porque espera un operando, el procesador se detiene hasta que pueda continuar. - **2. Emisión en orden y finalización desordenado:** Las instrucciones se emiten en el mismo orden en que aparecen en el programa, pero pueden ejecutarse en cualquier orden si no tienen dependencias entre sí. Si una instrucción no puede ejecutarse aún, el procesador busca otras instrucciones posteriores que sí puedan ejecutarse antes, optimizando el uso de los recursos. - **3. Emisión y Ejecución desordenada:** El procesador puede emitir y ejecutar instrucciones en cualquier orden, garantizando que el resultado final sea el mismo que en una ejecución secuencial. Para evitar los problemas de dependencias, se usa la técnica de renombre de registros que evitar los conflictos con los registros intermedios.
3) Elegir una de las 3 politicas emisión/finalización y justifique su elección. ACA ELEGI UNA DE LAS 3 QUE MAS TE CONVENGA Y JUSTIFICALA (CHAT GPT :v )
4) De que depende el paralelismo de una maquina super escalar - 1. **Dependecia de datos verdadera**: Cuando una instrucción necesita el resultado de una instrucción previa antes de poder ejecutarse. - 2. **Dependencia relativa del procesamiento**: Se refiere a las restricciones impuestas por el orden en que se deben emitir y ejecutar las instrucciones en un procesador. - 3. **Conflicto en los recursos**: Cuando múltiples instrucciones compiten por un mismo recurso al mismo tiempo. - 4. **Dependencia de salida**: Cuando dos instrucciones intentan escribir en el mismo registro. - 5. **Antidependencia**: Cuando una instrucción quiere escribir en un registro que todavía está siendo usada por otra instrucción previa.
5) Cual es el objetivo de usar la tecnica de renombre de registros en un procesador super escalar Es resolver problemas de dependencia entre instrucciones que intentan usar los mismos registros. Esto permite una ejecucion más eficiente y paralela de instrucciones.
6) Que es el paralelismo y de que depende el paralelismo de una maquina El paralelismo es la capacidad de un sistema para ejecutar múltiples operaciones al mismo tiempo, en lugar de procesarlas de manera secuencial. El paralelismo de una maquina depende: - 1. **Numero de instrucciones captadas por ciclo**: Cuantas más instrucciones se puedan decodificar y enviar al procesador en cada ciclo de reloj , mayor va a ser el aprovechamiento del paralelismo a nivel de instrucción. - 2. **Número de unidades funcionales**: A mayor número de unidades funcionales logra que más instrucciones se procesen en paralelo, siempre que sean independientes entre sí. - 3. **Mecanismo de localización de instrucciones independientes**: El procesador detecta las instrucciones que puedan ejecutarse en paralelo sin violar dependencias de datos o de control. Usando técnicas como el renombre de registros, predicción de saltos y la ejecución fuera de orden.

Memoria

1) Por que funciona un sistema de memoria basado en la jerarquia. Funciona gracias al principio de localidad de referencia basado en 2 tipos de acceso a memoria: - **Localidad Temporal**: hace referencia a que los elementos de memoria que fueron recientemente referenciados (como datos e instrucciones) se vuelvan a referenciar en el futuro cercano. - **Localidad Espacial**: hace referencia a que si un elemento de memoria fue referenciado, es probable que otros elementos cuyas direcciones están cercanas también sean referenciados.
2) Analice las politicas de escritura desde el punto de vista de la coerencia de datos ### Acierto - **Escritura inmediata (write-through)**: Cada escritura en caché se refleja inmediatamente en la memoria principal, por lo que se mantiene la coherencia de datos en todo momento, suele combinarse con la técnica **no-write-allocate.** - **Postescritura (write-back)**: Las actualizaciones se hacen en la cache y se marca un bit de “actualizar o sucio”. Cuando el bloque se saca de la cache se chequea ese bit si está activo, se escribe ese bloque en la memoria principal. Esto puede producir que la memoria principal tenga informacion errónea durante un tiempo. Suele combinarse con la técnica **write-allocate.** ### Fallo - **Write Allocate**: la informacion se lleva de memoria principal a la cache y se sobrescribe sobre ella , por lo que se puede alterar la coherencia de datos hasta que haya un remplazo de memoria principal. - **No write Allocate**: El bloque no se lleva a la memoria cache ,se escribe directamente en memoria principal.
3) Analice cuales son las ventajas y desventajas de tener varios niveles de cache Tener varios niveles de caché (L1, L2, L3) mejora el rendimiento al reducir la latencia y aprovechar la localidad temporal y espacial, optimizando el acceso. Además, permite un balance entre capacidad y velocidad. Sin embargo, aumenta la complejidad del diseño, incrementa los costos y el consumo de energía, y requiere mecanismos de coherencia entre niveles que pueden afectar el rendimiento.
4) Compare la correspondencia entre la memoria principal y la memoria cache. - **1. DIRECTA**: cada bloque de la memoria principal se mapea a una única línea en la caché. la dirección de memoria se divide en 3 campos para determinar en qué línea de caché se almacena el bloque de datos correspondiente. - **2. ASOCIATIVA**: cada bloque de memoria principal puede cargarse en cualquier línea de la cache. La lógica del control de la cache interpreta una dirección de memoria como una etiqueta y un campo de palabras. - **3. ASOCIATIVA POR CONJUNTO**: la cache se divide en v conjuntos, cada uno con k líneas. La lógica de control de la cache interpreta una dirección de memoria como 3 campos: etiqueta, conjunto y palabra.
5) Describe las funciones de correspondencia entre la cache y la memoria principal - **DIRECTA**: cada bloque de la memoria principal se mapea a una única línea en la caché. - **ASOCIATIVA**: cada bloque de memoria principal puede cargarse en cualquier línea de la cache. - **ASOCIATIVA POR CONJUNTO**: Un bloque puede almacenarse en un conjunto restringido de la cache.
6) Cuales son los elementos a tener en cuenta en el diseño de una memoria cache ### 1.El tamaño de la cache No se puede determinar un tamaño fijo optimo, pero a mayor tamaño se necesitas más circuitos para su gestión, las caches más grandes suelen ser un poco más lentas y su tamaño está limitado por el espacio disponible en el chip y las tarjetas. ### 2.Funcion de correspondencia Define cómo se asignan los bloques de memoria en la caché. - **DIRECTA**: cada bloque puede ir solo a una línea especifica. - **ASOCIATIVA**: cualquier bloque puede ir a cualquier línea. - **ASOCIATIVA POR CONJUNTO**: los bloques se asignas a un conjunto de líneas específicas. ### 3.Algoritmo de sustitución Decide qué bloque se reemplaza cuando la caché está llena. - **LRU**: se remplaza el bloque menos usado recientemente. - **LFU**: se remplaza el bloque menos accedido. - **FIFO**: se remplaza el bloque más antiguo. - **ALEATORIA**: Se reemplaza un bloque al azar. ### 4.Politica de escritura Cuando se debe reemplazar un bloque de la caché, si se ha realizado algún cambio en una línea de caché, es necesario escribir esos datos modificados en la memoria principal antes de hacer el reemplazo. - **Escritura inmediata**: Cada escritura en caché se refleja inmediatamente en la memoria principal. - **Postescritura**: Las actualizaciones se hacen en la cache y luego se sobrescriben en la memoria principal cuando el bloque se remplaza. ### 5.Tamaño de línea: Define cuántas palabras o bytes conforman un bloque en la caché. A Líneas más grandes se reducen la cantidad de accesos a la memoria principal, pero pueden generar desperdicio de almacenamiento si los datos no se utilizan completamente. ### 6.Numero de caches El diseño de caché en un sistema de cómputo puede abordarse desde dos perspectivas:' **1.Número de niveles de caché (caché multinivel vs. caché de un solo nivel)** - **Caché de un solo nivel** (L1 única):Es la primera y única caché entre el procesador y la memoria principal. Su acceso es rápido, pero si la información no está en caché, se debe ir directamente a la RAM, aumentando la latencia. - **Caché multinivel** (L1, L2, L3): Divide la caché en varios niveles, cada uno con diferentes tamaños y velocidades. - **L1**: Más rápida pero pequeña (cercana al procesador). - **L2**: Más grande que L1, pero más lenta. - **L3**: Mayor capacidad, compartida entre núcleos del procesador en muchos casos. Reduce la cantidad de accesos a la memoria RAM, mejorando el rendimiento. **2.Organización de la caché (unificada vs. separada):** - **Caché unificada**: Almacena tanto instrucciones como datos en una única caché. - **Cache separada**: Se divide en caché de instrucciones y caché de datos. Evita conflictos cuando el procesador necesita acceder a instrucciones y datos simultáneamente. Mejora el rendimiento en procesadores con segmentación de instrucciones.
7) Si se pretende el tiempo de acceso mediante la memoria cache sobre que parametro sera necesario trabajar y que propone como medidas para hacerlo. Para mejorar el tiempo de acceso medio en la memoria caché, es necesario optimizar los siguientes parámetros: - **1.Tamaño de la caché**: Aumentarlo puede reducir fallos, pero si es demasiado grande, puede volverse más lenta. Se debe encontrar un equilibrio. - **2.Función de correspondencia**: Usar asociatividad por conjuntos en lugar de mapeo directo reduce colisiones y mejora la tasa de aciertos. - **3.Tamaño de bloque**: Un tamaño adecuado minimiza reemplazos innecesarios y mejora la localidad espacial. - **4.Algoritmo de reemplazo**: LRU (menos recientemente usado) es eficiente, pero puede ser costoso en hardware. Alternativas como FIFO o reemplazo aleatorio pueden simplificar la implementación. - **5.Política de escritura**: Write-back en lugar de write-through reduce accesos innecesarios a la memoria principal. - **6.Cachés multinivel**: Usar una caché L2 o L3 de mayor tamaño y menor velocidad que L1 ayuda a reducir la frecuencia de accesos a la RAM. - **7.Separación de instrucciones y datos**: Evita competencia por el acceso y mejora el rendimiento en arquitecturas segmentadas.

Modulo de E/S y DMA

1) Como es la estructura de un modulo de entrada y salida, esquematice y describa ![image](https://github.com/user-attachments/assets/4956384b-96e2-4221-bf30-86fde8cae56e) - **Conexión del sistema**: el módulo de E/S se conecta con el resto del computador a través de las líneas del bus del sistema (datos, dirección, control). - Registro de Datos y estados: - **Registro de datos**: almacena temporalmente los datos que entran o salen de los dispositivos. - **Registro de estado**: indica el estado actual del dispositivo ( listo, ocupado, error). Puede funcionar también como registro de control para recibir instrucciones del procesador. - **Interacción con CPU:** La CPU utiliza las líneas de control para enviar ordenes al módulo E/S por ejemplo leer datos o escribir en un dispositivo. - **Reconocimiento de direcciones**: el módulo reconoce una dirección única para identificar que dispositivo controla. Si controla varios tiene un conjunto único de direcciones. - **Interfaz específica para dispositivos:** Contiene la lógica necesaria para comunicarse directamente con cada uno de los dispositivos conectados.
2) La coerencia de un sistema jerarquico se ve afectado por el uso del DMA Puede verse afectado, ya que si se realizan operaciones sobre un dato, este se actualiza en cache y si no se vacía la memoria antes de que un dispositivo intente accederlo, se podría estar usando un valor erróneo y viceversa.
3) Describa las caracteristicas funcionales del acceso directo a memoria El Acceso Directo a Memoria permite que un dispositivo periférico acceda a memoria principal (RAM) directamente sin la intervención de la CPU. El DMA acelera la transferencia de datos entre la memoria y los dispositivos periféricos, lo que libera recursos de la CPU para otras tareas. Las características funcionales del DMA incluyen varias etapas de transferencia: **Solicitud** La primera etapa implica que un dispositivo periférico envíe una solicitud de acceso a la memoria al controlador DMA. Esta solicitud incluye información sobre la dirección de memoria de origen y destino, la cantidad de datos a transferir y el sentido de la transferencia. Selección del Canal DMA: Los sistemas informáticos pueden tener múltiples canales, cada uno dedicado a un tipo específico de dispositivo o función. En esta etapa, el sistema debe asignar el canal DMA a la solicitud entrante. **Configuración** Una vez seleccionado el canal DMA, se configura para que coincida con los requisitos de la transferencia de datos. Esto incluye la configuración de las direcciones de inicio y finalización en la memoria, el tamaño de la transferencia y otras características relevantes. **Acceso Directo:** El controlador DMA se comunica directamente con la memoria principal y el dispositivo periférico para iniciar la transferencia de datos. La CPU no participa en la transferencia en sí, lo que permite que la CPU realice otras tareas mientras se lleva a cabo la transferencia. **Transferencia de Datos:** El controlador DMA transfiere datos entre la memoria y el dispositivo periférico utilizando el canal DMA configurado previamente. La transferencia puede ser en una dirección o bidireccional. **Finalización** Cuando se completa la transferencia, el controlador DMA notifica al dispositivo periférico y actualiza cualquier estado relevante. La CPU puede ser notificada de la finalización de la transferencia mediante una interrupción o un mecanismo similar. **Liberación del Canal DMA** Después de completar la transferencia, el canal DMA se libera para su uso posterior. Esto permite que otros dispositivos o solicitudes utilicen el canal DMA según sea necesario.
4) Describa el funcionamiento de gestion de entrada y salida programada con espera de respuesta inicia una operación de E/S (como leer o escribir datos en un dispositivo de almacenamiento, por ejemplo), y luego espera a que el dispositivo de E/S termine la operación antes de continuar con su ejecución. En este modelo, el procesador se "bloquea" o "espera" mientras la operación de E/S se lleva a cabo. **Funcionamiento paso a paso:** - **Iniciar la operación de E/S**: El procesador envía una solicitud al dispositivo de E/S para realizar una operación específica (por ejemplo, leer un bloque de datos de un disco duro o escribir datos en una impresora). - **Espera de respuesta**: Una vez que el procesador emite la solicitud de E/S, espera que el dispositivo termine la operación. Durante este tiempo, el procesador no realiza ninguna otra tarea, ya que está esperando que se complete la operación solicitada. - **Polling**: El procesador revisa periódicamente el estado del dispositivo de E/S para determinar si la operación ha finalizado. Esto es menos eficiente que el uso de interrupciones. - **Procesamiento de los datos**: Después de que el dispositivo ha terminado la operación, y el procesador ha recibido la respuesta el procesador puede procesar los datos que fueron leídos o verificar que los datos fueron escritos correctamente.
5) Desarrolle el funcionamiento del DMA y a los usos que de el se hacen. El controlador de DMA recibe el control del sistema cedido por el procesador, para transferir datos a y desde memoria a través del bus del sistema. Para hacerlo, el DMAC debe utilizarlo sólo cuando el procesador no lo necesita, o forzar al procesador a que suspenda temporalmente su funcionamiento, a esto se lo conoce como robo de ciclo. Cuando el procesador desea leer o escribir un bloque de datos, envía una orden al módulo de DMA, incluyendo: - Si se solicita una lectura o una escritura. - La dirección del dispositivo de E/S en cuestión, indicada a través de las líneas de datos. - La posición inicial de memoria a partir de donde se lee o se escribe, indicada a través del bus de datos y almacenada por el DMAC en su registro de direcciones. - El número de palabras a leer o escribir, indicado a través de las líneas de datos y almacenado en el registro de cuenta de datos. El procesador continúa su trabajo y el DMAC transfiere el bloque completo de datos, palabra a palabra, directamente desde o hacia la memoria. Cuando la transferencia ha terminado, el DMAC envía una señal de interrupción al procesador.

Buses

1) Que elementos caracteristicos describen un bus **1) Tipos de buses** - **Dedicado:** El bus esta permanentemente asignado a una función o a un subconjunto especifico de componentes dentro del sistemas. - **Multiplexado:** Utiliza las mismas lineas de comunicación para diferentes funciones o componentes en diferentes momentos **2) Metodo de arbitraje** - **Centralizado:** Un dispositivo o unidad de control se encarga de gestionar el acceso al buss, asignado el tiempo de uso a cada componente - **Distribuido:** Cada modulo o componente tiene su propia logica para acceder al buss y los modulos colaboran para compartir los recursos **3) Temporización** - **Sincronica:** El funcionamiento del bus esta cordinado por un reloj y todos los elementos del bus dependen de este. - **Asincronica:** Los eventos del buss no dependen de un reloj central sino que son impulsadas por eventos previos y señales de control **4) Anchura de buss** La anchura de bus se refiere al nro de lineas que tiene el bus, lo que determina la cantidad de información que puede tranmitirse simultaneamente. - En el buss de datos, la anchura indica cuantos bits se pueden transferir de manera paralela - En el bus de direcciones la anchura determina el tamaño de memoria que se puede direccionar. **5) Tipo de transferencia de datos** - **Transferencia de escritura:** El bus permite que el maestro envie datos al exclavo - **Transferencia de lectura:** El esclavo envia datos al maestro. Algunos buses permiten operaciones combinadas como: - 1) Lectura-Modificación-Lectura: Una lectura seguida de una escritura en la misma dirección - 2) Lectura-Despues-Escritura: Una escritura seguida de una lectura en la misma dirección Ademas, algunos buses permiten transferencias de bloques de datos donde multiples datos se transfieren en un solo ciclo

Maquina/Arquitectura

1) Que elementos caracteristicos describen un bus 1) Que elementos componen una maquina con arquitectura Von Newman descrir funcion de cada componente ***Unidad Central de Procesamiento (CPU):*** Es el componente principal encargado de ejecutar las instrucciones del programa. Se divide en: - **Unidad de Control (CU)**: Coordina la ejecución de instrucciones, decodificándolas y enviando señales de control a los demás componentes. - **Unidad Aritmético-Lógica (ALU)**: Realiza operaciones matemáticas y lógicas. - **Registros**: Pequeñas unidades de almacenamiento dentro de la CPU que guardan datos temporales y direcciones. **Memoria Principal:** Almacena datos e instrucciones de los programas en ejecución. Es de acceso aleatorio (RAM), lo que permite una lectura y escritura rápida por parte del procesador. **Bus de Datos, Dirección y Control:** Permiten la comunicación entre los componentes de la máquina. - **Bus de Datos**: Transporta los datos entre la memoria, la CPU y los dispositivos de entrada/salida. - **Bus de Direcciones**: Indica la ubicación de los datos en la memoria. - **Bus de Control**: Transporta señales de control que coordinan el funcionamiento de los demás buses y dispositivos. **Unidad de Entrada/Salida (E/S)**: Permite la interacción entre la computadora y el usuario o dispositivos externos. Incluye teclados, pantallas, discos duros, impresoras, entre otros.

Finales

image image image

💻Practica 2

Ejercicios

1 ) Implementar un programa en el lenguaje assembler que muestre en la pantalla de comandos un mensaje previamente almacenado en memoria de datos, aplicando la interrupción por software INT 7 Resolucion

2 ) Escribir un programa que muestre en pantalla todos los caracteres disponibles, comenzando con el caracter cuyo código es el número 01H Resolucion

3 ) Escribir un programa que muestre en pantalla las letras del abecedario, sin espacios, intercalandolo mayúsculas y minúsculas (AaBb…), sin incluir texto en la memoria de datos del programa. Tener en cuenta que el código de “A” es 41H, el de “a” es 61H y que el resto de los codigos son correlativos según el abecedario Resolucion

4 ) Escribir un programa que solicite el ingreso de un número (de un digito) por teclado e inmediatamente lo muestre en la pantalla de comandos, haciendo uso de las interrupciones por software INT 6 e INT 7. Resolucion

5 ) Modificar el programa anterior agregando una subrutina llamada ES_NUM que verifique si el caracter ingresado es realmente un número. De no serlo, el programa debe mostrar el mensaje “CARACTER NO VALIDO”. La subrutina debe recibir el código del caracter por referencia desde el programa principal y debe devolver vía registro el valor 0FFH en caso de tratarse de un número o el valor 00H en caso contrario. Tener en cuenta que el código del “0” es 30H y el del “9” es 39H. Resolucion

6 ) Escribir un programa que solicite el ingreso de un número (de un dígito) por teclado y muestre en pantalla dicho número expresado en letras. Luego que solicite el ingreso de otro y así sucesivamente. Se debe finalizar la ejecución al ingresarse en dos vueltas consecutivas el número cero. Resolución

7 ) Escribir un programa que efectúe la suma de dos números (de un dígito cada uno) ingresados por teclado y muestre el resultado en la pantalla de comandos. Recordar que el código de cada caracter ingresado no coincide con el número que representa y que el resultado puede necesitar ser expresado con 2 dígitos. Resolución

8 ) Escribir un programa que efectúe la resta de dos números (de un dígito cada uno) ingresados por teclado y muestre el resultado en la pantalla de comandos. Antes de visualizarlo el programa debe verificar si el resultado es positivo o negativo y anteponer al valor el signo correspondiente. Resolución

9 ) Escribir un programa que aguarde el ingreso de una clave de cuatro caracteres por teclado sin visualizarla en pantalla. En caso de coincidir con una clave predefinida (y guardada en memoria) que muestre el mensaje “Acceso permitido”, caso contrario el mensaje “Acceso denegado”. Resolución

10 ) Escribir un programa que, mientras ejecuta un lazo infinito, cuente el número de veces que se presiona la tecla F10 y acumule este valor en el registro DX. Resolución

11 ) Escribir un programa que permita seleccionar una letra del abecedario al azar. El código de la letra debe generarse en un registro que incremente su valor desde el código de A hasta el de Z continuamente. La letra debe quedar seleccionada al presionarse la tecla F10 y debe mostrarse de inmediato en la pantalla de comandos. Resolución

12 ) Implementar a través de un programa un reloj segundero que muestre en pantalla los segundos transcurridos (00-59 seg) desde el inicio de la ejecución. Resolución

15 ) Escribir un programa que implemente un conteo regresivo a partir de un valor ingresado desde el teclado. El conteo debe comenzar al presionarse la tecla F10. El tiempo transcurrido debe mostrarse en pantalla, actualizándose el valor cada segundo. Resolución

Ejercicio_1

ORG 1000H
 MENSAJE DB "ARQUITECTURA DE COMPUTADORAS-"
         DB "FACULTAD DE INFORMATICA-"
         DB 55H
         DB 4EH
         DB 4CH
         DB 50H
 FIN DB ?
ORG 2000H
 MOV BX, OFFSET MENSAJE
 MOV AL, OFFSET FIN - OFFSET MENSAJE
 INT 7    
 INT 0
END

Ejercicio_2

ORG 1000H
 MENSAJE DB 01H
ORG 2000H
 MOV BX, OFFSET MENSAJE
 MOV AL, 1 ;Solo voy a imprimir un caracter
 REPETIR: INT 7    
 INC BYTE PTR [BX]
 CMP BYTE PTR [BX], 7FH
 JNZ REPETIR
 INT 0
END

Ejercicio_3

ORG 1000H
 MAY DB 41H ; "A"
 MIN DB 61H ; "a"
 ; La letra "Z" (mayuscula) tiene el codigo 5A
ORG 2000H
 MOV AL, 2 		       ; SE IMPRIME EN PANTALLA DE A 2 CARACTERES
 MOV BX, OFFSET MAY ; A PARTIR DE LA DIRECCION MAY
 PROX: INT 7
 INC MIN            ;PASO AL SIGUIENTE CARACTER
 INC MAY            ;PASO AL SIGUIENTE CARACTER
 CMP MAY, 5BH       ;CARACTER SIGUIENTE A LA Z (ASI TOMO LA Z)
 JNZ PROX           ;MIENTRAS NO LLEGUE AL CARACTER, AVANZO
 INT 0
END

Ejercicio_4 ===========

ORG 1000H
 MSJ DB "INGRESE UN NUMERO:"
 FIN DB ?
ORG 1500H
 NUM DB ?
ORG 2000H
 MOV BX, OFFSET MSJ  ;PARA IMPRIMIR SIEMPRE TIENE SER EL REGISTRO BX
 MOV AL, OFFSET FIN-OFFSET MSJ
 INT 7               ;IMPRIMO EL MENSAJE NORMAL 
 MOV BX, OFFSET NUM  ;PARA TOMAR EL VALOR PUEDE SER CUALQUIER REGISTRO
 INT 6               ;INGRESO UN VALOR POR TECLADO Y LO CARGO A NUM
 MOV AL, 1           ;AL INDICA LA CANTIDAD DE CARACTERES
 INT 7
 MOV CL, NUM
 INT 0
END

Responder brevemente:

a ) Con referencia a la interrupción INT 7, ¿Qué se almacena en los registros BX y AL?

En BX se almacena la direccion de memoria en donde comienza el string, y en AL se almacena la cantidad de caracteres que voy a imprimir.

b ) Con referencia a la interrupción INT 6, ¿Qué se almacena en BX?

En BX se tiene la dirección de memoria donde se va a guardar el carácter el caracter leido.

c ) En el programa anterior, ¿Qué hace la segunda interrupción INT 7? ¿Qué queda almacenado en el registro CL?

Como en bx, quedo guardado la direccion del numero que ingresamos, luego a AL, mando 1 para que solo me imprima el caracter leido. En el registro CL queda el codigo ASCII del caracter leido.

Ejercicio_5

ORG 1000H
 MENSAJE DB "INGRESE UN NUMERO: "
 FIN DB ?
 MENSAJE2 DB "CARACTER NO VALIDO"
 FIN2 DB ?
 NUEVE DB 39H
ORG 1500H    ;ESTA PUEDE SER CUALQUIER DIRECCION, LO PONEMOS POR COMODIDAD
 NUM DB ?
 
ORG 3000H
 ES_NUM:INT 6
 CMP NUM,30H
 JS NO_ES      ;SI EL VALOR ES MENOR AL 0, NO ES VALIDO
 CMP  NUM,40H  ;SI EL VALOR ES MAYOR A 9, TAMPOCO ES VALIDO
 JNS NO_ES
 
 MOV DX,0FFH   ;MANDO ESTE VALOR PARA INDICAR QUE ES CORRECTO
 MOV AL, 1     ;IMPRIMO SOLO 1 CARACTER
 INT 7
 JMP TERMINO   ;TERMINO NORMAL
 
 NO_ES: MOV DX, 00H       ;MANDO EL VALOR E IMPRIMO EL MENSAJE
 MOV BX, OFFSET MENSAJE2
 MOV AL, OFFSET FIN2-OFFSET MENSAJE2
 INT 7
 
TERMINO: RET

ORG 2000H 
 MOV BX, OFFSET MENSAJE
 MOV AL, OFFSET FIN-OFFSET MENSAJE
 INT 7
 
 MOV BX, OFFSET NUM
 CALL ES_NUM
 
 MOV CL, NUM ;MANDO EL CARACTER/NUMERO INGRESADO
 INT 0
END

Ejercicio_6 ===========

ORG 1000H
 CERO DB "CERO " ; Todos los nombres tienen 6 caracteres para 
      DB "UNO " ; facilitar posicionarnos al imprimir el nombre del numero
      DB "DOS "
      DB "TRES "
      DB "CUATRO"
      DB "CINCO "
      DB "SEIS "
      DB "SIETE "
      DB "OCHO "
      DB "NUEVE "
 MSJ DB "INGRESE UN NUMERO:"
 FIN DB ?
 
ORG 1500H
 NUM DB ?
 
ORG 2000H
 MOV CL, 0                      ; CONT 0 DE FORMA CONSECUTIVA
 OTRO: MOV BX, OFFSET MSJ
 MOV AL, OFFSET FIN-OFFSET MSJ
 INT 7                          ; IMPRIMO EL MENSAJE
 
 MOV BX, OFFSET NUM
 INT 6                          ; LEO UN CARACTER
 CMP NUM, 30H                   ; COMPARO CON 0
 JNZ NO_CERO
 
 INC CL                         ; VOY A NRO 1
 JMP SEGUIR
 
 NO_CERO:MOV CL, 0              ;REINICIO EL CONTADOR DE 0 CONSECUTIVOS
 
 SEGUIR: MOV BX, OFFSET CERO 
  MOV AL, 6                     ;IMPRIMO SIEMPRE 6 CARACTERES
 
 LOOP: CMP NUM, 30H
  JZ IMPRIME                    ;SI ENCONTRE EL NOMBRE, IMPRIMO
   ADD BX, 6                    ;AVANZO DE NOMBRE
   DEC NUM                      ;AL LLEGAR AL NUMERO 0, ESTARA POSICIONADO
  JMP LOOP
  
 IMPRIME:INT 7
  CMP CL, 2
  JNZ OTRO                      ; HASTA QUE SE INGRESE DOS VECES SEGUIDAS EL "0" CERO
 INT 0 
END

Ejercicio_7 ===========

ORG 1000H
 MSJ DB "INGRESE UN NUMERO:"
 FIN DB ?
 ORG 1500H
 NUM1 DB ?
 NUM2 DB ?
 RES_D DB "0"                  ; DOCENA DEL RESULTADO 
 RES_U DB ?                    ; UNIDAD DEL RESULTADO

ORG 2000H
 MOV BX, OFFSET MSJ
 MOV AL, OFFSET FIN-OFFSET MSJ
 INT 7                         ;IMPRIMO EL MENSAJE
 MOV BX, OFFSET NUM1
 INT 6                         ;LEO EL NUM1
 MOV BX, OFFSET MSJ
 INT 7                         ;PIDO OTRO NUMERO
 MOV BX, OFFSET NUM2
 INT 6                         ;LEO EL NUM2
 MOV AL, NUM2 
 SUB AL, 30H                   ; PARA QUEDARME CON EL ENTERO
 
 ADD AL, NUM1                  ; SUMO EL PRIMER NUMERO
 CMP AL, 3AH                   ; SI NO SUPERO 9, IMPRIMO
 JS NUM_OK                     ; SI ES MENOR QUE 9
 
 SUB AL, 10                    ; ME QUEDO CON LA UNIDAD
 INC RES_D                     ;PASA DE SER "0" A "1"
 
 NUM_OK: MOV RES_U, AL         ;COPIO EL VALOR EN RES U
 MOV BX, OFFSET RES_D          ; IMPRIMO 2 CARACTERES
 MOV AL, 2
 INT 7
 INT 0
END

Ejercicio_8

ORG 1000H
 MSJ DB "INGRESE UN NUMERO:"
 FIN DB ?
 ORG 1500H
 NUM1 DB ?
 NUM2 DB ?
 RES_D DB "0"                  ; DOCENA DEL RESULTADO 
 RES_U DB ?                    ; UNIDAD DEL RESULTADO

ORG 2000H
 MOV BX, OFFSET MSJ
 MOV AL, OFFSET FIN-OFFSET MSJ
 INT 7                         ;IMPRIMO EL MENSAJE
 MOV BX, OFFSET NUM1
 INT 6                         ;LEO EL NUM1
 MOV BX, OFFSET MSJ
 INT 7                         ;PIDO OTRO NUMERO
 MOV BX, OFFSET NUM2
 INT 6                         ;LEO EL NUM2
 MOV AL, NUM1 
 
 CMP AL, NUM2                  ;SI EL RESULTADO DA NEGATIVO
 JS NUM_NO_OK                  
 SUB AL, NUM2                  ;SINO, ES UNA RESTA NORMAL
 JMP NUM_OK                    ;IMPRIMO EL NUMERO
 
 NUM_NO_OK: MOV AL, NUM2
 SUB AL, NUM1               
 MOV RES_D, 2DH                     ;PASA DE SER "0" A "-"
 
 NUM_OK: ADD AL, 30H
 MOV RES_U, AL         
 MOV BX, OFFSET RES_D          ; IMPRIMO 2 CARACTERES
 MOV AL, 2
 INT 7
 INT 0
END

Ejercicio_9 ===========

ORG 1000H
MSJ DB "INGRESE UN NUMERO:"
FIN DB ?
CONTRA DB "AB"
CONTRA_PARTE2 DB "CZ"
CANT DB 4H

MENSAJE DB "CORRECTA"
FIN_MENSAJE DB ?
MENSAJE2 DB "INCORRECTA"
FIN_MENSAJE2 DB ?

ORG 3000H
 LEER_CONTRA:MOV BX, SP
 ADD BX,2
 BUCLE: MOV CL,[BX]
 MOV DX, BX
 MOV BX, OFFSET NUM
 INT 6
 MOV AL, 1
 INT 7
 
 CMP CL,NUM
 JNZ INCORRECTO
 
 MOV BX, DX
 INC BX
 DEC CANT
 JNZ BUCLE
 
 CMP CANT,0
 JZ CUMPLE
 
 INCORRECTO: MOV BX, OFFSET MENSAJE2
 MOV AL, OFFSET FIN_MENSAJE2 - OFFSET MENSAJE2
 INT 7 
 JMP TERMINAR
 
 
 CUMPLE:MOV BX, OFFSET MENSAJE
 MOV AL, OFFSET FIN_MENSAJE - OFFSET MENSAJE
 INT 7 
 JMP TERMINAR
 
TERMINAR: RET

ORG 1500H
NUM DB ?

ORG 2000H
MOV BX, OFFSET MSJ
MOV AL, OFFSET FIN-OFFSET MSJ
INT 7
MOV BX, CONTRA_PARTE2
PUSH BX
MOV BX, CONTRA
PUSH BX
CALL LEER_CONTRA

INT 0
END

Ejercicio_10 ============

PIC EQU 20H
EOI EQU 20H
N_F10 EQU 10

ORG 40
 IP_F10 DW RUT_F10
ORG 2000H
CLI
 MOV AL, 0FEH     ; 11111110
 OUT PIC+1, AL    ; PIC: IMR, ACTIVO F10
 MOV AL, N_F10    ; ELEGIMOS ID
 OUT PIC+4, AL    ; PIC: INT0, GUARDAMOS LA ID
 MOV DX, 0
STI
 LAZO: JMP LAZO

ORG 3000H
 RUT_F10: PUSH AX
 INC DX
 MOV AL, EOI
 OUT EOI, AL      ; PIC: EOI
 POP AX
 IRET
END

Explicar detalladamente:

a) La función de los registros del PIC: ISR, IRR, IMR, INT0-INT7, EOI. Indicar la dirección de cada uno.

ISR: Sus bits indican si se está atendiendo la interrupción de algún dispositivo. Sólo importan los 4 bits menos significativos.

IRR: Sus bits indican qué dispositivos están solicitando una interrupción. Si el bit N vale 1, entonces el dispositivo conectado a la línea INTN está haciendo una solicitud. Sólo importan los 4 bits menos significativos.

IMR: sus bits indican qué líneas de interrupción están habilitadas. Si el bit N vale 1, las interrupciones del dispositivo conectado a la línea INTN serán ignoradas. Si vale 0, las interrupciones del dispositivo serán atendidas en algún momento. Sólo importan los 4 bits menos significativos

INT0

b) Cuáles de estos registros son programables y cómo trabaja la instrucción OUT.

c) Qué hacen y para qué se usan las instrucciones CLI y STI.

Ejercicio_11

ORG 3000H
CONTAR: INT 7
 MOV AL, 20H
 OUT 20H, AL
IRET

ORG 1000H
CARACTER DB "A"

ORG 2000H
;CONFIGURO EL VECTOR DE INTERRUPCIONES
 MOV AX, CONTAR 
 MOV BX, 40 
 MOV [BX], AX 

 
 CLI
 MOV AL, 11111110B      ;ACTIVO EL F10
 OUT 21H, AL            ;MANDO AL SMR LOS DATOS
 MOV AL, 10             ;ID 10
 OUT 24H, AL            ;MANDO LA ID A INT0
 STI
 
 MOV BX, OFFSET CARACTER
 
 REINICIAR: MOV BYTE PTR [BX],40H
 
 LOOP: INC BYTE PTR [BX];AUMENTO EL CARACTER
 MOV AL,1
 MOV AH,0
 CMP BYTE PTR [BX],5AH  ;SI LLEGO A LA Z, REINICIO
 JZ REINICIAR
 JMP LOOP 
INT 0
END

Ejercicio_12 ============

ORG 1000H
 SEG DB 30H
     DB 30H
 FIN DB ?
 
ORG 3000H
 RUT_CLK: PUSH AX
 
 ;VAMOS SUMANDO DEL 00 AL 09
 MOV BX, OFFSET SEG
 INC BX
 INC BYTE PTR [BX]
 CMP BYTE PTR [BX], 3AH
 JNZ RESET
 
 ;VAMOS SUMANDO DEL 00 AL 60 (En la direccion que le sigue a segundo)
 ;COMIENZO EN EL SEGUNDO DIGITO
 MOV BYTE PTR [BX], 30H ;iniciamos en 0
 DEC BX ;SEG
 INC BYTE PTR [BX]
 CMP BYTE PTR [BX], 36H ;Hasta el 60
 JNZ RESET
 
 MOV BYTE PTR [BX], 30H
 
 RESET: MOV BX, OFFSET SEG ;REINICIAMOS EL ESTADO DE SEGUNDOS
 MOV AL, OFFSET FIN-OFFSET SEG ;PORQUE LO USAMOS MAS ARRIBA
 INT 7
 MOV AL, 0
 OUT 10H, AL
 MOV AL, 20H
 OUT 20H, AL
 POP AX
IRET
 
ORG 2000H
 ;ID 10 PARA EL TIMER
 ;CONFIGURAMOS EL VECTOR DE INTERRUPCIONES
 MOV AX, RUT_CLK
 MOV BX, 40
 MOV [BX], AX
 ;CONFIGURAMOS EL PIC
 CLI
 MOV AL, 11111101b ;Activamos el timer
 OUT 21H, AL ; PIC: registro IMR
 
 MOV AL, 10
 OUT 25H, AL ; PIC: registro INT1 (Timer)
 MOV AL, 1
 OUT 11H, AL ; TIMER: registro COMP 
 MOV AL, 0
 OUT 10H, AL ; TIMER: registro CONT
 STI
 
 LAZO: JMP LAZO
END

Ejercicio_15 ============

ORG 3000H
;Subrutina que atiende a la F10
CONTAR: INT 6
 MOV AL, 1 
 MOV DX, LEIDO
 
 DECREMENTAR: INT 7
 DEC LEIDO
 CMP LEIDO, 30H
 JNZ DECREMENTAR
 
 MOV AL, 0
 
 ;AVISAR AL PIC QUE TERMINAMOS!
 OUT 10H, AL
 MOV AL, 20H
 OUT 20H, AL

 ;VOLVEMOS
IRET

ORG 1000H
 LEIDO DB ?
 FIN DB ?

ORG 2000H
 ;SELECCIONAR ID 10 PARA EL F10
  
 ;CONFIGURAMOS EL VECTOR DE INTERRUPCIONES
 MOV AX, CONTAR ;AX = Dir de CONTAR(3000H)
 MOV BX, 40 ;10 * 4 en el Vec. de Int.
 MOV [BX], AX ;EN LA POSICION 40 PONE EL 3000H

 ;CONFIGURAMOS EL PIC
 CLI
 MOV AL, 11111100B ;Configuramos solo el INT0 (F10) Y EL TIMER (F11)
 OUT 21H, AL  ;IMR
 MOV AL, 10
 OUT 24H, AL ;ID 10(PUEDE SER CUALQUIERA)
 INC AL ;MANDAMOS LA ID 11 PARA EL TIMER
 OUT 25H, AL 
 MOV AL, 10 ;ES 10, POR SI LO CAMBIO
 OUT 11H, AL ; TIMER: registro COMP 
 MOV AL, 0
 OUT 10H, AL ; TIMER: registro CONT
 STI
 
 MOV BX, OFFSET LEIDO
 LOOP: JMP LOOP ;LOOP INFINITO
 
INT 0
END

💻Practica 3

Ejercicios

1 ) Uso de las luces y las llaves a través del PIO. Ejecutar los programas bajo la configuración P1 C0 del simulador, que conecta las llaves al puerto PA del PIO y a las luces al puerto PB.

a ) Escribir un programa que encienda las luces con el patrón 11000011, o sea, solo las primeras y las últimas dos luces deben prenderse, y el resto deben apagarse. Resolución

b ) Escribir un programa que verifique si la llave de más a la izquierda está prendida. Si es así, mostrar en pantalla el mensaje “Llave prendida”, y de lo contrario mostrar “Llave apagada”. Solo importa el valor de la llave de más a la izquierda (bit más significativo). Recordar que las llaves se manejan con las teclas 0-7. Resolucion

c ) Escribir un programa que permite encender y apagar las luces mediante las llaves. El programa no deberá terminar nunca, y continuamente revisar el estado de las llaves, y actualizar de forma consecuente el estado de las luces. La actualización se realiza simplemente prendiendo la luz i si la llave i correspondiente está encendida (valor 1), y apagándola en caso contrario. Por ejemplo, si solo la primera llave está encendida, entonces solo la primera luz se debe quedar encendida. Resolución

d ) Escribir un programa que implemente un encendido y apagado sincronizado de las luces. Un contador, que inicializa en cero, se incrementa en uno una vez por segundo. Por cada incremento, se muestra a través de las luces, prendiendo solo aquellas luces donde el valor de las llaves es 1. Entonces, primero se enciende solo la luz de más a la derecha, correspondiente al patrón 00000001. Luego se continúa con los patrones 00000010, 00000011, y así sucesivamente. El programa termina al llegar al patrón

  1. Resolución

e ) Escribir un programa que encienda una luz a la vez, de las ocho conectadas al puerto paralelo del microprocesador a través de la PIO, en el siguiente orden de bits: 0-1-2-3-4-5-6-7-6-5-4-3-2-1-0-1-2-3-4-5-6-7-6-5-4-3-2-1-0-1-…, es decir, 00000001, 00000010, 00000100, etc. Cada luz debe estar encendida durante un segundo. El programa nunca termina. Resolución

2 ) Ejecutar los programas en la configuración P1 C1 del simulador. En esta configuración, el puerto de datos de la impresora se conecta al puerto PB del PIO, y los bits de busy y strobe de la misma se conectan a los bits 0 y 1 respectivamente del puerto PA. Presionar F5 para mostrar la salida en papel. El papel se puede blanquear ingresando el comando BI.

a ) Escribir un programa para imprimir la letra “A” utilizando la impresora a través de la PIO. Resolución

b ) Escribir un programa para imprimir el mensaje “ORGANIZACION Y ARQUITECTURA DE COMPUTADORAS” utilizando la impresora a través de la PIO. Resolución

c ) Escribir un programa que solicita el ingreso de cinco caracteres por teclado y los envía de a uno por vez a la impresora a través de la PIO a medida que se van ingresando. No es necesario mostrar los caracteres en la pantalla. Resolución

d ) Escribir un programa que solicite ingresar caracteres por teclado y que recién al presionar la tecla F10 los envíe a la impresora a través de la PIO. No es necesario mostrar los caracteres en la pantalla. Resolución

3 ) Uso de la impresora a través del HAND-SHAKE. Ejecutar los programas en configuración P1 C2

a ) Escribir un programa que imprime “INGENIERIA E INFORMATICA” en la impresora a través del HAND-SHAKE. La comunicación se establece por consulta de estado (polling). ¿Qué diferencias encuentra con el ejercicio 2b? Resolución

b ) ¿Cuál es la ventaja en utilizar el HAND-SHAKE con respecto al PIO para comunicarse con la impresora? Sacando eso de lado, ¿Qué ventajas tiene el PIO, en general, con respecto al HANDSHAKE? Resolución

c ) Escribir un programa que imprime “UNIVERSIDAD NACIONAL DE LA PLATA” en la impresora a través del HAND-SHAKE. La comunicación se establece por interrupciones emitidas desde el HANDSHAKE cada vez que la impresora se desocupa. Resolución

d) Escribir un programa que solicite el ingreso de cinco caracteres por teclado y los almacene en memoria. Una vez ingresados, que los envíe a la impresora a través del HAND-SHAKE, en primer lugar tal cual fueron ingresados y a continuación en sentido inverso. Utilizar el HAND-SHAKE en modo consulta de estado. ¿Qué diferencias encuentra con el ejercicio 2c? Resolución

e ) Idem d ) , pero ahora utilizar el HAND-SHAKE en modo interrupciones. Resolución

Ejercicio_1a

CB EQU 33h
PB EQU 31h

ORG 1000H     
 PATRON db 0C3h;1100 0011b
 
ORG 2000H
 MOV AL, 0
 OUT CB, AL      ;CONFIGURO TODOS DE SALIDA
 MOV AL, PATRON
 OUT PB, AL      ;IMPRIMO PATRON
 INT 0
END

Ejercicio_1b ============

CA EQU 32h
PA EQU 30h

ORG 1000H
 PRENDIDA DB "Llave prendida"
 APAGADA DB "Llave apagada"
 FIN_APAGADA DB ?

ORG 2000H
 MOV AL, 0FFh
 OUT CA, AL     ;TODO SALIDA
 IN AL, PA
 ; poner en 0 todos los bits menos el más sig
 AND AL, 80h;1000 0000
 ; si es 0
 CMP AL, 0
 JZ ESTA_APAGADA
 ; esta prendida
 MOV BX, OFFSET PRENDIDA
 MOV AL,OFFSET APAGADA - OFFSET prendida
 JMP FIN
 
 ESTA_APAGADA: MOV BX, OFFSET APAGADA
 MOV AL, OFFSET FIN_APAGADA - OFFSET APAGADA
 FIN: INT 7 ; imprimir
 HLT
END

Ejercicio_1c ============

PA EQU 30H
PB EQU 31H
CA EQU 32H
CB EQU 33H

ORG 2000H
MOV AL, 0FFH 
OUT CA, AL        ; CONFIGURO PA COMO ENTRADAS (LLAVES)
MOV AL, 0         
OUT CB, AL        ; CONFIGURO PB COMO SALIDAS (LUCES)

POLL: IN AL, PA   ; MIRO COMO ESTAN LAS LLAVES
OUT PB, AL        ; MUESTRO EL VALOR DE LAS LLAVES EN LAS LUCES
JMP POLL          ; LOOP INFINITO
END

Ejercicio_1d ============

PIC EQU 20H
TIMER EQU 10H
PIO EQU 30H
N_CLK EQU 10

ORG 40
 IP_CLK DW RUT_CLK
 
ORG 1000H
 PATRON DB 0
 FINAL DB 0
 
ORG 3000H
 RUT_CLK: INC PATRON
  CMP PATRON, 0FFH    ;COMPARO CON 11111111B
  JNZ LUCES           ;MIENTRAS NO LLEGUE AL ULTIMO, SALTO
  MOV FINAL, 1
  MOV AL, 0FFH
  OUT PIC+1, AL       ;DESHABILITO TODAS LAS INTERRUPCIONES
  JMP FIN
  
  LUCES: MOV AL, PATRON
   OUT PIO+1, AL      ; PB IMPRIME EL PATRON DE LAS LUCES
   MOV AL, 0          
   OUT TIMER, AL      ; REINICIO LOS SEGUNDOS
  FIN: MOV AL, 20H    ; VUELVO NORMAL
   OUT PIC, AL
 IRET
 
ORG 2000H
 CLI
 MOV AL, 0FDH
 OUT PIC+1, AL   ;ACTIVO EL TIMER EN ISMR
 
 MOV AL, N_CLK   ;PASO LA ID 10
 
 OUT PIC+5, AL   ;PONGO LA ID EN INT1: TIMER
 MOV AL, 1
 OUT TIMER+1, AL ;PONGO UN 1 EN EL COMP (SEGUNDOS)
 MOV AL, 0
 OUT PIO+3, AL   ;CONFIGURO PB PARA QUE SEAN TODAS DE SALIDA (LUCES)
 OUT PIO+1, AL   ;INICIO LAS LUCES EN 0
 OUT TIMER, AL   ; INICIO EL CONTADOR EN 0
 STI
 
 LAZO: CMP FINAL, 1
 JNZ LAZO
 INT 0

END

Ejercicio_1d ============

PIC EQU 20H
TIMER EQU 10H
PIO EQU 30H
N_CLK EQU 10

ORG 40
 IP_CLK DW RUT_CLK
 
ORG 1000H
 PATRON DB 1
 FINAL DB 0
 REVERSO DB 0
 VALOR DB 0

ORG 1500H
 TABLA DB 1,2,4,8,16,32,64,128
 
ORG 3000H
 RUT_CLK:  CMP REVERSO, 1
  JZ MODO_REVERSO
  MOV CL, BYTE PTR [BX]
  INC BX
  CMP BYTE PTR [BX], 128    ;COMPARO CON 10000000B
  JNZ LUCES                 ;MIENTRAS NO LLEGUE AL ULTIMO, SALTO
  MOV REVERSO, 1
  JMP LUCES
  
  MODO_REVERSO: MOV CL, BYTE PTR [BX]
  DEC BX
  CMP BYTE PTR [BX], 1 ;CUANDO LLEGO A 1, DESACTIVO EL REVERSO
  JNZ LUCES
  MOV REVERSO, 0
  
  
  
  LUCES: MOV AL, CL
   OUT PIO+1, AL      ; PB IMPRIME EL PATRON DE LAS LUCES
   MOV AL, 0          
   OUT TIMER, AL      ; REINICIO LOS SEGUNDOS
   MOV AL, 20H    ; VUELVO NORMAL
   OUT PIC, AL
 IRET
 
ORG 2000H
 MOV BX, OFFSET TABLA
 
 CLI
 MOV AL, 0FDH
 OUT PIC+1, AL   ;ACTIVO EL TIMER EN ISMR
 
 MOV AL, N_CLK   ;PASO LA ID 10
 
 OUT PIC+5, AL   ;PONGO LA ID EN INT1: TIMER
 MOV AL, 1
 OUT TIMER+1, AL ;PONGO UN 1 EN EL COMP (SEGUNDOS)
 MOV AL, 0
 OUT PIO+3, AL   ;CONFIGURO PB PARA QUE SEAN TODAS DE SALIDA (LUCES)
 OUT PIO+1, AL   ; INICIO LAS LUCES EN 0
 OUT TIMER, AL   ; INICIO EL CONTADOR EN 0
 STI
 
 LAZO: JMP LAZO
 INT 0

END

Ejercicio_2a ============

PA EQU 30h
PB EQU 31h
CA EQU 32h
CB EQU 33h

ORG 1000H
 CHAR DB "A"

ORG 2000H
 MOV AL, 01h; ; STROBE SALIDA (0), BUSY ENTRADA (1), RESTO EN 0
 OUT CA, AL
 MOV AL, 0    ;PUERTO DE DATOS, TODO SALIDA
 OUT CB, AL

 ; inicializo strobe en 0
 IN AL, PA
 AND AL, 0FDh ; 1111 1101b
 OUT PA, AL

 ; espero que busy=0
 POLL: IN AL, PA
 AND AL, 01h ;0000 0001b
 JNZ POLL

 ; se que busy es 0, mandar carácter
 MOV AL, CHAR
 OUT PB, AL

 ; mandar flanco ascendente de strobe
 IN AL, PA
 OR AL, 02h; 00000010b
 OUT PA, AL
 INT 0
END

Ejercicio_2b ============

PIO EQU 30H

ORG 1000H
 MSJ DB "CONCEPTOS DE "
     DB "ARQUITECTURA DE "
     DB "COMPUTADORAS"
 FIN DB ?
 
ORG 2000H
 ; INICIALIZACION PIO PARA IMPRESORA
 ; CA
 MOV AL, 0FDH     ;1111 1101B
 OUT PIO+2, AL    ;STROBE DE SALIDA, BUSY DE ENTRADA
 
 ; CB
 MOV AL, 0
 OUT PIO+3, AL   ;TODOS DE SALIDA
 
 ; Strobe
 IN AL, PIO
 AND AL, 0FDH
 OUT PIO, AL    ; PONGO EN 0 EL STROBE
 
 ; FIN INICIALIZACION
 MOV BX, OFFSET MSJ
 MOV CL, OFFSET FIN-OFFSET MSJ
 POLL: IN AL, PIO
 AND AL, 1
 JNZ POLL
 
 ; Enviar carácter
 MOV AL, [BX]
 OUT PIO+1, AL
 
 ; Pulso STROBE
 IN AL, PIO
 OR AL, 02H     ;ACTIVO EL STROBE
 OUT PIO, AL    ;MUESTRO EL STROBE
 
 ; Reiniciar STROBE
 IN AL, PIO
 AND AL, 0FDH
 OUT PIO, AL
 INC BX ;Mover el puntero de la cadena
 DEC CL
 JNZ POLL ; Verificar fin de la cadena
 INT 0
END

Ejercicio_2c ============

PIO EQU 30H

ORG 1000H
 NUM_CAR DB 5
 CAR DB  ?
; SUBRUTINA DE INICIALIZACION
; PIO PARA IMPRESORA

ORG 3000H
 INI_IMP: MOV AL, 0FDH
 OUT PIO+2, AL         ;CA TROBE DE SALIDA, BUSY DE ENTRADA
 MOV AL, 0
 OUT PIO+3, AL         ;CB TODOS DE SALIDA
 IN AL, PIO            ; PONEMOS EL STROBE EN 0 PARA EMPEZAR
 AND AL, 0FDH          
 OUT PIO, AL
RET

; SUBRUTINA DE GENERACIÓN DE PULSO "STROBE"
ORG 4000H
 PULSO: IN AL, PIO 
 OR AL, 02H          ; PONGO EL STROBE EN 1
 OUT PIO, AL
 IN AL, PIO
 AND AL, 0FDH        ; PONGO EL STROBE EN 0
 OUT PIO, AL
RET


; PROGRAMA PRINCIPAL
ORG 2000H
 PUSH AX
 CALL INI_IMP
 POP AX
 MOV BX, OFFSET CAR
 MOV CL, NUM_CAR
 
 LAZO: INT 6        ; INGRESO UN CARACTER
 POLL: IN AL, PIO   ; CHEQUEAMOS EL ULTIMO BIT DE PA
 AND AL, 1
 JNZ POLL           ; MIENTRAS NO ESTE LIBRE, SIGO EJECUTANDO
 
 MOV AL, [BX]       ; MANDO EL DIGITO QUE LEI
 OUT PIO+1, AL
 
 PUSH AX
 CALL PULSO        ; LO IMPRIMO
 POP AX
 DEC CL
 JNZ LAZO          ; ASI CON LOS 5 CARACTERES
INT 0
END

Ejercicio_2d ============

EOI EQU 20h
IMR EQU 21h
INT0 EQU 24h
IDINT0 EQU 10
PA EQU 30h
PB EQU 31h
CA EQU 32h
CB EQU 33h

ORG 1000H
 FLAG db 0
 LONGITUD db 0
 CADENA db ?

ORG 40
 dir_rut dw rut_f10

ORG 3000h
; cancelar interrupciones futuras (DESACTIVAR)
rut_f10: MOV AL,0FFH
OUT IMR, AL
;indicamos al programa que no lea más
MOV FLAG, 1
MOV AL, 24h
OUT EOI, AL
IRET

ORG 2000H
 cli
 ; INICIALIZACION PIO PARA IMPRESORA
 MOV AL, 0FDH     ; EL STROBE COMO SALIDA Y EL STROBE COMO SALIDA
 OUT CA, AL
 MOV AL, 0
 OUT CB, AL       ; TODOS COMO SALIDA
 IN AL, PA
 AND AL, 0FDH     ;PONEMOS EL STROBE EN 0
 OUT PA, AL
 
 ;INICIALIZACIÓN DEL PIC
 MOV AL, 0FEh    ; FE = 1111 1110
 OUT IMR, AL     ; ACTIVAMOS EL F10
 MOV AL, IDINT0
 OUT INT0, AL    ; MANDAMOS LA ID AL F10
 STI
 
 ; LECTURA DE CADENA
 MOV BX, OFFSET CADENA
 LOOP: INT 6     ; leer char
 INC BX
 INC LONGITUD
 CMP FLAG, 0     ; verifico si presionaron f10
 JZ LOOP

 ; IMPRESIÓN DE LOS CARACTERES LEIDOS
 MOV BX, OFFSET CADENA  ; VAMOS AL INICIO DE LA CADENA
 POLL: NOP              ; NOP: LITERALMENTE NO HACE NADA
  IN AL, PA             ; VERIFICAMOS QUE LA IMPRESORA ESTE LIBRE PARA IMPRIMIR
  AND AL, 1
 JNZ POLL
 
 ; ENVIAMOS EL CARACTER
 MOV AL, [BX]
 OUT PB, AL
 
 ; Pulso STROBE PARA IMPRIMIR
 IN AL, PA
 OR AL, 02H
 OUT PA, AL
 
 ; Reiniciar STROBE 
 IN AL, PA
 AND AL, 0FDH
 OUT PA, AL
 
 ; pasar al siguiente char
 INC BX
 DEC LONGITUD
 JNZ POLL
INT 0
END

Ejercicio_3a ============

HAND EQU 40H

ORG 1000H
 MSJ DB "INGENIERIA E "
 DB "INFORMATICA"
 FIN DB ?
 
ORG 2000H
 IN AL, HAND+1
 AND AL, 7FH
 OUT HAND+1, AL
 MOV BX, OFFSET MSJ
 MOV CL, OFFSET FIN-OFFSET MSJ
 POLL: IN AL, HAND+1
 AND AL, 1
 JNZ POLL
 MOV AL, [BX]
 OUT HAND, AL
 INC BX
 DEC CL
 JNZ POLL
 INT 0
END

Ejercicio_3b ============ El handshake con respecto al pio:

El hanshake sabe hacer algunas funciones que no sabe hacer el pio (La cpu no necesita realizar algunas tareas). Con el hanshake puedo trabajar por interrupciones tambien, cosa que no puedo con el pio.

El pio con respecto al handshake:

El pio sirve para varios dispositivos (No con la impresora nada mas), es como un modulo general, en cambio en el handshake solo puedo usar la impresora, es como un modulo dedicado a la impresora. La pio es mas general. Si solo pienso en la impresora, no tengo ventajas con respecto al handshake, ya que este tiene funciones extras.

Ejercicio_3c

PIC EQU 20H
HAND EQU 40H
N_HND EQU 10

ORG 1000H
 MENSAJE DB "UNIVERSIDAD         "
         DB "NACIONAL DE LA PLATA"
 FIN DB ?

ORG 40
 IP_HND DW RUT_HND

ORG 3000H
 RUT_HND: PUSH AX
 MOV AL, [BX]
 OUT HAND, AL
 INC BX
 DEC CL
 JNZ FINAL
 MOV AL, 0FFH
 OUT PIC+1, AL
 
 FINAL: MOV AL, 20H
 OUT PIC, AL
 POP AX
IRET

ORG 2000H
 MOV BX, OFFSET MENSAJE
 MOV CL, OFFSET FIN - OFFSET MENSAJE
 CLI
 MOV AL, 0FBH
 OUT PIC+1, AL
 MOV AL, N_HND
 OUT PIC+6, AL
 MOV AL, 80H
 OUT HAND+1, AL
 STI
 
 LAZO: CMP CL, 0
 JNZ LAZO
 
 IN AL, HAND+1
 AND AL, 7FH
 OUT HAND+1, AL
 
INT 0
END

Ejercicio_3d ============

HAND_DATO EQU 40H
HAND_ESTADO EQU 41H

ORG 1000H
 FIN DB 5
 MENSAJE DB ""
 

ORG 2000H
;CONFIGURO EL HANDSHAKE PARA EL POOLING
IN AL, HAND_ESTADO
AND AL, 01111111B        ;7FH MODIFICO SOLO EL ULTIMO BIT
OUT HAND_ESTADO, AL      ;ESTADO = 0XXXXXXX

;RECORREMOS EL MENSAJE Y LO ENVIAMOS POR CARACTER A LA IMPRESORA
MOV BX, OFFSET MENSAJE   ;PARA RECORRER EL MENSAJE
MOV DL, FIN
LAZO: INT 6    ; INGRESO UN CARACTER
 INC BX
 DEC DL
 CMP DL, 0
 JNZ LAZO
 ;CONTADOR
 MOV BX, OFFSET MENSAJE ;PARA COMENZAR EL CONTEO
 MOV DL, FIN


;DESOCUPO LA IMPRESORA
POLL: IN AL, HAND_ESTADO ;TOMO EL ESTADO ACTUAL
AND AL, 1                ;CHEQUEO EL PRIMER BIT
JNZ POLL                 ;MIENTRAS SEA 1 SIGO EN EL LOOP

; IMPRIMO 
MOV AL, [BX]             ;TOMO EL CARACTER
OUT HAND_DATO, AL        ;LO ENVIO AL REGISTRO DE DATOS

; AVANZO
INC BX                   ;AVANZO A LA SIGUIENTE POSICION
DEC DL
CMP DL, 0       ;CHEQUEO SI LLEGUE AL FINAL
JNZ POLL

INT 0
END

Ejercicio_3e ============

ORG 1000H
 FIN DB 5
 MENSAJE DB ?
 
 
ORG 3000H
;RECORREMOS EL MENSAJE Y LO ENVIAMOS POR CARACTER
IMPRIMIR: PUSH AX
 MOV AL, [BX] 
 OUT 40H, AL
;AVISO AL PIC Y VUELVO
INC BX
DEC DL
JNZ CONTINUAR
;DESACTIVO HANDSHAKE POR INTERRUPCION
MOV AL, 01111111B
OUT 21H, AL
;___________________________________
CONTINUAR: MOV AL, 20H
OUT 20H, AL
POP AX
IRET


ORG 2000H
 ;CONFIGURO EL VECTOR DE INTERRUPCIONES. ID = 9
 MOV AX, IMPRIMIR
 MOV BX, 36       ;9*4 = 36
 MOV [BX], AX
 
 ;CONTADOR
 MOV BX, OFFSET MENSAJE ;PARA COMENZAR EL CONTEO
 MOV DL, FIN
 
 LAZO: INT 6    ; INGRESO UN CARACTER
 INC BX
 DEC DL
 CMP DL, 0
 JNZ LAZO
 ;CONTADOR
 MOV BX, OFFSET MENSAJE ;PARA COMENZAR EL CONTEO
 MOV DL, FIN
 
 ;CONFIGURO PIC
 CLI
 MOV AL, 11111011B ;SOLO HANDSHAKE HABILITADO (0FBH)
 OUT 21H, AL ; IRM
 MOV AL, 9   ; ID = 9
 OUT 26H, AL ; MANDO LA ID AL INT2 (HANDSHAKE)
 
 ;CONFIGURO EL HANDSHAKE PARA LA INTERRUPCION
 OR AL, 10000000B    ; MANDO UN 1 AL MENOS SIGNIFICATIVO 
 OUT 41H, AL         ; ACTIVO EL HANDSHAKE COMO INTERRUPCION
 STI
 
 ;SIMULAMOS UN PROGRAMA EN EJECUCION
 POLL: CMP DL, 0    ; CHEQUEO QUE SE TERMINO EL CONTADOR
 JNZ POLL   
 
 IN AL, 41H                
 AND AL, 7FH         ; 0111 1111
 OUT 41H, AL         ; DESACTIVO EL HANSHAKE COMO INTERRUPCION

INT 0
END

💻Practica 4

Segmentación de cauce en procesador RISC

1 ) Muchas instrucciones comunes en procesadores con arquitectura CISC no forman parte del repertorio de instrucciones del MIPS64, pero pueden implementarse haciendo uso de una única instrucción. Evaluar las siguientes instrucciones, indicar qué tarea realizan y cuál seria su equivalente en el lenguaje assembly del x86. Resolución

a) dadd r1, r2, r0
b) daddi r3, r0, 5
c) dsub r4, r4, r4
d) daddi r5, r5, -1
e) xori r6, r6, 0xffffffffffffffff

2 ) El siguiente programa intercambia el contenido de dos palabras de la memoria de datos, etiquetadas A y B.

.data
    A: .word 1
    B: .word 2
.code
    ld r1, A(r0)
    ld r2, B(r0)
    sd r2, A(r0)
    sd r1, B(r0)
halt

a ) Ejecutarlo en el simulador con la opción Configure/Enable Forwarding deshabilitada. Analizar paso a paso su funcionamiento, examinar las distintas ventanas que se muestran en el simulador y responder: Resolución

b ) Una forma de solucionar los atascos por dependencia de datos es utilizando el Adelantamiento de Operandos o Forwarding. Resolución

Ejecutar nuevamente el programa anterior con la opción Enable Forwarding habilitada y responder:

3 ) Analizar el siguiente programa con el simulador MIPS64:

.data
    A: .word 1
    B: .word 3
.code
    ld r1, A(r0)
    ld r2, B(r0)
    loop: dsll r1, r1, 1
        daddi r2, r2, -1
        bnez r2, loop
halt

a ) Ejecutar el programa con Forwarding habilitado y responder: Resolución

b ) Ejecutar ahora el programa deshabilitando el Forwarding y responder: Resolución

Comparar con la ejecución con Forwarding y explicar la diferencia.

c ) Reordenar las instrucciones para que la cantidad de RAW sea „0‟ en la ejecución del programa (Forwarding habilitado) Resolución

d ) Modificar el programa para que almacene en un arreglo en memoria de datos los contenidos parciales del registro r1 ¿Qué significado tienen los elementos de la tabla que se genera? Resolución

4 ) Dado el siguiente programa

.data
    tabla: .word 20, 1, 14, 3, 2, 58, 18, 7, 12, 11
    num: .word 7
    long: .word 10
.code
    ld R1, long(R0)         ; R1  = 10
    ld R2, num(R0)          ; R2 = 7
    dadd R3, R0, R0         ; R3 = R0 + R0 (INICIALIZO R3)
    dadd R10, R0, R0        ; R10 = R0 + R0 (INICIALIZO R10)

    loop: ld R4, tabla(R3)  ; R4 = TABLA + R3(POS) RECORRO LA TABLA
        beq R4, R2, listo   ; SI EL NRO DE LA TABLA ACTUAL ES IGUAL AL NRO QUE ESTOY BUSCANDO, TERMINO
        daddi R1, R1, -1    ; DECREMENTO EL CONTADOR DE TABLA
        daddi R3, R3, 8     ; R3 = R3 + 8 (CADA NRO EN LA TABLA OCUPA 1 BYTE QUE SON 8 BITS)
        bnez R1, loop       ; MIENTRAS NO LLEGUE AL FINAL, CONTINUO

    j fin                   ; TERMINO
    listo: daddi R10, R0, 1 ; R10 = 0 + 1 ; QUIERO ENTENDER QUE ES PARA AVISAR QUE ENCONTRE EL NRO
fin: halt

a ) Ejecutar en simulador con Forwarding habilitado. ¿Qué tarea realiza? ¿Cuál es el resultado y dónde queda indicado? Resolución

b) Re-Ejecutar el programa con la opción Configure/Enable Branch Target Buffer habilitada. Explicar la ventaja de usar este método y cómo trabaja. Resolución

c) Confeccionar una tabla que compare número de ciclos, CPI, RAWs y Branch Taken Stalls para los dos casos anteriores. Resolución

5 ) El siguiente programa multiplica por 2 los elementos de un arreglo llamado datos y genera un nuevo arreglo llamado res. Ejecutar el programa en el simulador winmips64 con la opción Delay Slot habilitada. Resolución

.data
    cant: .word 8
    datos: .word 1, 2, 3, 4, 5, 6, 7, 8
    res: .word 0
.code
    dadd R1, R0, R0         ;INICIALIZO R1
    ld R2, cant(R0)         ; R2 = 8
    loop: ld R3, datos(R1)  ; R3 = ELEMENTO DE TABLA EN X POSICION
        daddi R2, R2, -1    ; DECREMENTO EL CONTADOR DE TABLA
        dsll R3, R3, 1      ; MUEVO LOS BITS UNA POSICION A LA IZQUIERDA QUE SERIA EL EQUIVALENTE A MULTIPLICARLOS X2
        sd R3, res(R1)      ; R3 = REMPLAZO EL VALOR NUEVO EN LA TABLA
        daddi R1, R1, 8     ; ME MUEVO AL SIGUIENTE ELEMENTO DE LA TABLA
        bnez R2, loop       ; MIENTRAS NO TERMINE DE RECORRER LA TABLA, CONTINUO
    nop
halt

a ) ¿Qué efecto tiene habilitar la opción Delay Slot (salto retardado)?.

b ) ¿Con qué fin se incluye la instrucción NOP? ¿Qué sucedería si no estuviera?.

c ) Tomar nota de la cantidad de ciclos, la cantidad de instrucciones y los CPI luego de ejecutar el programa.

d ) Modificar el programa para aprovechar el „Delay Slot‟ ejecutando una instrucción útil. Simular y comparar número de ciclos, instrucciones y CPI obtenidos con los de la versión anterior.

6 ) Escribir un programa que lea tres números enteros A, B y C de la memoria de datos y determine cuántos de ellos son iguales entre sí (0, 2 o 3). El resultado debe quedar almacenado en la dirección de memoria D. Resolución

7 ) Escribir un programa que recorra una TABLA de diez números enteros y determine cuántos elementos son mayores que X. Resolución

El resultado debe almacenarse en una dirección etiquetada CANT. El programa debe generar además otro arreglo llamado RES cuyos elementos sean ceros y unos. Un „1‟ indicará que el entero correspondiente en el arreglo TABLA es mayor que X, mientras que un „0‟ indicará que es menor o igual.

8 ) Escribir un programa que multiplique dos números enteros utilizando sumas repetidas (similar a Ejercicio 6 o 7 de la Práctica 1). El programa debe estar optimizado para su ejecución con la opción Delay Slot habilitada. Resolución

Ejercicio_1

# dadd r1, r2, r0   R1 = R2 + R0
# daddi r3, r0, 5   R3 = R0 + 5
# dsub r4, r4, r4   R4 = R4 - R4
# daddi r5, r5, -1  R5 = R5 + -1
# xori r6, r6, 0xffffffffffffffff  R6 = R6 XOR 0xffffffffffffffff

Ejercicio_2a

La instrucción SD R2, A(r0) almacena en la dirección de memoria A el valor contenido en el registro R2, mientras que la instrucción anterior LD R2, B(r0) carga desde la dirección de memoria B el contenido de esa posición en el registro R2.

Cuando fordwarding no está habilitado la instrucción SD R2, A(r0) que en la etapa ID trata de leer el contenido de R2, pero dicho contenido no estará disponible hasta que la instrucción anterior LD R2, B(r0) llegue a la etapa WB.

Y debido a esto se genera un atasco en la etapa ID donde se procesa la instrucción SD R2, A(r0) retrasando la salida de la etapa (con RAWs) a la espera del contenido del registro. Esto además genera que la instrucción posterior SD R1, B(r0) deba permanecer en la etapa IF sin poder avanzar a la etapa ID (el pipeline se detuvo) como se puede ver en la imagen.

Tener en cuenta que en la primera mitad de la etapa WB se escribe el contenido en R2 y en el segundo RAW se lee el contenido de dicho registro.

image

Aparecen atascos de tipo RAW (Read After Write) causado por una dependencia de datos, en este caso intenta leer un dato antes que esté guardado en el registro. Serán dos atascos, equivalentes a dos ciclos hasta que LD R2, B(r0) salga de la estapa WB.

El CPI de la ejecución de este programa es de 2.2

Ejecución Funciones
![image](https://user-images.githubusercontent.com/55964635/140979278-78e2e908-83cc-4ee5-9544-b9d857686baa.png) Ciclos por instrucción (CPI) = 2,2 Espera por dependencia de datos (RAW) = 2

Ejercicio_2b

Con la opción forwarding habilitada el dato contenido en el registro R2 podrá ser leído por la instrucción SD R2, A(r0) cuando la instrucción LD R2, B(r0) se encuentra finalizando la etapa MEM. La instrucción SD R2, A(r0) no tiene que esperar a que la instrucción LD R2, B(r0) salga de la etapa WB. De esta manera no aparecen atascos del tipo RAW.

image

Ejercicio_3a

Se presentan atasco por dependencia de datos de tipo RAW causado por la instrucción BNEZ R2, loop al procesarse en la etapa ID. Esta instrucción necesita del contenido del registro R2 que está siendo utilizado por la instrucción DADDI R2,R2, -1 en la etapa EX sin salir aún de esta.

El atasco de tipo Branch Taken Stalls (BTS), ocurre como concecuencia de la ejecución incorrecta de la instrucción siguiente a una instrucción condicional. Esto se debe a que la condición a evaluar tarda algunos ciclos en ser ejecutada, mientras que durante esos ciclos siguen entrando nuevas instrucciones al pipeline. Luego de evaluada la condición si la instrucción posterior a ésta que se ejecutó no es la que debía ser ejecutada, su ejecución se trunca y se ejecuta la que está en el lugar de memoria indicada por la etiqueta en la instrucción condicional.

image

Se ejecutan 12 instrucciones en 21 ciclos dando un CPI de 1.750

image

Ejercicio_3b

Las instrucciones que generan atascos RAW son:

la instrucción DSLL R1,R1,1 (ver registro R1 coloreado en gris), que trata de leer el contenido del registro R1, mientras que la instrucción LD R1,A(r0) todavía no copio el contenido de la dirección de memoria A en R1 y permanece aún en la etapa WB (RAW durante 1 ciclo).

Y la instrucción BNEZ R2,loop (ver registro R2 coloreado en gris), que trata de leer el contenido del registro R2, mientras que DADDI R2,R2,-1 está buscando copiar el resultado de la operación en dicho registro, permaneciendo en la etapa MEM y posteriormente en la etapa WB (RAW durante 2 ciclos).

image

Con forwarding deshabilitada, Los atascos por Branch Taken Stalls duran 2 ciclos en cada vuelta del lazo loop, mientras que con dicha opción habilitada se reducen a 1 ciclo por vuelta de lazo.

Esta diferencia tiene su causa en la instrucción condicional que es la que está generando los atascos RAW; entonces al disminuir la cantidad de RAWs producidos por esta, también disminuyen los ciclos de espera de la instrucción siguiente, que además se dejara de ejecutar si la condicional así se lo indica al procesador.

a completar

Ejercicio_3c

Con la opción forwarding habilitada aún siguen apareciendo atascos RAW. Existe la posibilidad de tratar de eliminarlos reordenando las instrucciones en el programa y Dicho reordenamiento no debe afectar la lógica de este. El resultado de este método puede observarse en la imagen siguiente.

image

image

Ejercicio_3d


Ejercicio_4a
============

![image](https://user-images.githubusercontent.com/55964635/141165757-05440f46-6fb1-4c37-8c53-7952e3fdbfb6.png)

Ejercicio_4b
============

Ejercicio_4c
============

El programa busca en TABLA un elemento igual al contenido en la dirección de memoria NUM. En este caso dicha coincidencia se produce cuando el contenido del registro R4 es igual al contenido del registro R2 (R4=R2), razón por la cual luego de evaluada esta condición y de resultar verdadera se salta a la posición de memoria indicada por la etiqueta “listo”. Cuando hay coincidencia la línea de programa en listo suma al registro R10 un 1, caso contrario el contenido del registro R10 queda en 0. Este es el resultado y queda almacenado en el registro R10. El registro R3 se utiliza como índice para recorrer la TABLA. El contenido del registro R3 se incrementa de a 8 porque cada elemento de tabla es del tamaño word, es decir de 64 bits (8 bytes).

Habilitando la opción Branch Target Buffer (BTB) logramos reducir los atascos Branch Taken stalls a la mitad.

Tener en cuenta que esta opción es útil cuando aumenta la cantidad de iteraciones de un lazo. Como vemos también esta opción no actúa sobre los atascos por dependencia de datos (RAW en este caso) que no se modifican. 


Ejercicio_5
===========

Ejercicio_6
===========

```s
.data
    NROA: .word 1
    NROB: .word 2
    NROC: .word 1
    NROD: .word 0

.code
    ld R1, NROA(R0) 
    ld R2, NROB(R0) 
    ld R3, NROC(R0)
    ld R4, NROD(R0)

    
    bne R1, R2, continuar
    DADDI R4, R4, 2
    bne R1, R3, continuar2
    DADDI R4, R4, 1
    j TERMINAR

    continuar: bne R1, R3, TERMINAR
    DADDI R4, R4, 2
    bne R3, R2, TERMINAR
    DADDI R4, R4, 1
    j TERMINAR

    continuar2: bne R2, R3, TERMINAR
    DADDI R4, R4, 2

    TERMINAR: sd R4, NROD(R0)


    FIN: HALT

Ejercicio_7

.data
    TABLA: .word 1,2,3,4,5,6,7,8,9,10
    X: .word 6
    CANT: .word 0
    RES: .word 0

.code
    DADDI R10, R0, -8
    DADDI R11, R0, 80
    LD R1, X(R0)
    DADDI R4, R0, 1
    LD R5, CANT(R0)

    LOOP: DADDI R10, R10, 8
        BEQ R10, R11, FIN
        LD R2, TABLA(R10)
        SLT R3, R1, R2
        BNE R3, R4, LOOP
        DADDI R5, R5, 1
        SD R4, RES(R10)
        j LOOP
    FIN: SD R5, CANT(R0)
    HALT

Ejercicio_8

.data
    NUM1: .word 3
    NUM2: .word 5
    RES: .word 0
.code
    ld R1, NUM1(r0) ; 3
    ld R2, NUM2(r0) ; 8
    dadd R3, R0, R0
    loop: dadd R3, R3, R1
        daddi R2,R2, -1
        bnez R2, loop
    sd R3, RES(r0)
halt

con delay slot activado

.data
    num1: .word 3
    num2: .word 5
    res: .word 0
.code
    LD r1, num1(r0)
    LD r2, num2(r0)
    DADD r10, r0, r0
    LOOP: DADDI r2, r2, -1
        BNEZ r2, LOOP
        DADD r10, r10, r1
        SD r10, res(r0)
    HALT

💻Practica 5

Instrucciones de Punto Flotante y pasaje de parámetros

1) Simular el siguiente programa de suma de números en punto flotante y analizar minuciosamente la ejecución paso a paso. Inhabilitar Delay Slot y mantener habilitado Forwarding. Resolución

.data
    n1: .double 9.13
    n2: .double 6.58
    res1: .double 0.0
    res2: .double 0.0
.code
    l.d f1, n1(r0)
    l.d f2, n2(r0)
    add.d f3, f2, f1
    mul.d f4, f2, f1
    s.d f3, res1(r0)
    s.d f4, res2(r0)
    halt

a) Tomar nota de la cantidad de ciclos, instrucciones y CPI luego de la ejecución del programa.

b) ¿Cuántos atascos por dependencia de datos se generan? Observar en cada caso cuál es el dato en conflicto y las instrucciones involucradas.

c) ¿Por qué se producen los atascos estructurales? Observar cuales son las instrucciones que los generan y en qué etapas del pipeline aparecen.

d) Modificar el programa agregando la instrucción mul.d f1, f2, f1 entre las instrucciones add.d y mul.d. Repetir la ejecución y observar los resultados. ¿Por qué aparece un atasco tipo WAR?

e) Explicar por qué colocando un NOP antes de la suma, se soluciona el RAW de la instrucción ADD y como consecuencia se elimina el WAR.

2) Es posible convertir valores enteros almacenados en alguno de los registros r1-r31 a su representación equivalente en punto flotante y viceversa. Describa la funcionalidad de las instrucciones mtc1, cvt.1.d, cvt.d.1 y mfc1. Resolución

3) Escribir un programa que calcule la superficie de un triángulo rectángulo de base 5,85 cm y altura 13,47 cm. Resolución

Pista: la superficie de un triángulo se calcula como:

Superficie = (base x altura) / 2

4) El índice de masa corporal (IMC) es una medida de asociación entre el peso y la talla de un individuo. Resolución

Se calcula a partir del peso (expresado en kilogramos, por ejemplo: 75,7 kg) y la estatura (expresada en metros, por ejemplo 1,73 m), usando la fórmula:

IMG = PESO / (ESTATURA)^2

De acuerdo al valor calculado con este índice, puede clasificarse el estado nutricional de una persona en:

Infrapeso (IMC < 18,5), Normal (18,5 ≤ IMC < 25), Sobrepeso (25 ≤ IMC < 30) y Obeso (IMC ≥ 30).

Escriba un programa que dado el peso y la estatura de una persona calcule su IMC y lo guarde en la dirección etiquetada IMC. También deberá guardar en la dirección etiquetada estado un valor según la siguiente tabla:

IMC Clasificación Valor guardado
< 18,5 Infrapeso 1
< 25 Normal 2
< 30 Sobrepeso 3
>=30 Obeso 4

5) El procesador MIPS64 posee 32 registros, de 64 bits cada uno, llamados r0 a r31 (también conocidos como $0 a $31). Resolución

Sin embargo, resulta más conveniente para los programadores darles nombres más significativos a esos registros.

La siguiente tabla muestra la convención empleada para nombrar a los 32 registros mencionados:

Registros Nombres ¿Para que se los utiliza? ¿Preservado?
r0 $zero 1  
r1 $at 2  
r2-r3 $v0-$v1 3  
r4-r7 $a0-$a3 4  
r8-r15 $t0-$t7 4  
r16-r23 $s0-$s7 4  
r24-r25 $t8-$t9 4  
r26-r27 $k0-$k1 4  
R28 $gp 4  
R29 $sp 4  
R30 $fp 4  
R31 $ra 4  

Complete la tabla anterior explicando el uso que normalmente se le da cada uno de los registros nombrados. Marque en la columna “¿Preservado?” si el valor de cada grupo de registros debe ser preservado luego de realizada una llamada a una subrutina. Puede encontrar información útil en el apunte Programando sobre MIPS64

6) Como ya se observó anteriormente, muchas instrucciones que normalmente forman parte del repertorio de un procesador con arquitectura CISC no existen en el MIPS64. En particular, el soporte para la invocación a subrutinas es mucho más simple que el provisto en la arquitectura x86 (pero no por ello menos potente). El siguiente programa muestra un ejemplo de invocación a una subrutina. Resolución

.data
    valor1: .word 16
    valor2: .word 4
    result: .word 0
    
.text
    ld $a0, valor1($zero)
    ld $a1, valor2($zero)
    jal a_la_potencia
    sd $v0, result($zero)
    halt

a_la_potencia: daddi $v0, $zero, 1
    lazo: slt $t1, $a1, $zero
    bnez $t1, terminar
    daddi $a1, $a1, -1
    dmul $v0, $v0, $a0
    j lazo
    terminar: jr $ra

a) ¿Qué hace el programa? ¿Cómo está estructurado el código del mismo?

b) ¿Qué acciones produce la instrucción jal? ¿Y la instrucción jr?

c) ¿Qué valor se almacena en el registro $ra? ¿Qué función cumplen los registros $a0 y $a1? ¿Y el registro $v0?

d) ¿Qué sucedería si la subrutina a_la_potencia necesitara invocar a otra subrutina para realizar la multiplicación, por ejemplo, en lugar de usar la instrucción dmul? ¿Cómo sabría cada una de las subrutinas a que dirección de memoria deben retornar?

7) Escriba una subrutina que reciba como parámetros un número positivo M de 64 bits, la dirección del comienzo de una tabla que contenga valores numéricos de 64 bits sin signo y la cantidad de valores almacenados en dicha tabla. La subrutina debe retornar la cantidad de valores mayores que M contenidos en la tabla. Resolución

8) Escriba una subrutina que reciba como parámetros las direcciones del comienzo de dos cadenas terminadas en cero y retorne la posición en la que las dos cadenas difieren. En caso de que las dos cadenas sean idénticas, debe retornar -1. Resolución

9) Escriba la subrutina ES_VOCAL, que determina si un carácter es vocal o no, ya sea mayúscula o minúscula. La rutina debe recibir el carácter y debe retornar el valor 1 si el carácter es una vocal, o 0 en caso contrario. Resolución

10) Usando la subrutina escrita en el ejercicio anterior, escribir la subrutina CONTAR_VOC, que recibe una cadena terminada en cero , y devuelve la cantidad de vocales que tiene esa cadena. Resolución

11) Escribir una subrutina que reciba como argumento una tabla de números terminada en 0. La subrutina debe contar la cantidad de números que son impares en la tabla, esta condición se debe verificar usando una subrutina es_impar. La subrutina es_impar debe devolver 1 si el número es impar y 0 si no lo es. Resolución

12) El siguiente programa espera usar una subrutina que calcule en forma recursiva el factorial de un número entero: Resolución

data
    valor: .word 10
    result: .word 0
.text
    daddi $sp, $zero, 0x400 ; Inicializa puntero al tope de la pila
    (1)
    ld $a0, valor($zero)
    jal factorial
    sd $v0, result($zero)
    halt
factorial: ...
...

(1) La configuración inicial de la arquitectura del WinMIPS64 establece que el procesador posee un bus de direcciones de 10 bits para la memoria de datos. Por lo tanto, la mayor dirección dentro de la memoria de datos será de 2^10 = 1024 = 400 sub 16

a) Implemente la subrutina factorial definida en forma recursiva. Tenga presente que el factorial de un número entero n se calcula como el producto de los números enteros entre 1 y n inclusive:

factorial(n) = n! = n * (n - 1) * (n - 2) * ... * 3 * 2 * 1

b) ¿Es posible escribir la subrutina factorial sin utilizar una pila? Justifique.

Ejercicios

Ejercicio_1

a) 16 ciclos, 7 instrucciones y 2,286 Ciclos por Instrucción (CPI)

b) Se generan dos atascos por dependencia de datos

Ejercicio_2

Ejercicio_3

Resultado 39,39975 exa 3C 1E87

Ejercicio_4

Ejercicio_5 ===========

Registros Nombres ¿Para que se los utiliza? ¿Preservado?
r0 $zero Siempre tiene el valor 0 y no se puede cambiar  
r1 $at Return Address- Dir. de retorno de subrutina. Debe ser salvado  
r2-r3 $v0-$v1 Valores de retorno de la subrutina llamada  
r4-r7 $a0-$a3 Argumentos pasados a la subrutina llamada  
r8-r15 $t0-$t7 Registros temporarios  
r16-r23 $s0-$s7 Registros que deben ser salvados  
r24-r25 $t8-$t9 Registros temporarios  
r26-r27 $k0-$k1 Para uso del kernel del sistema operativo  
R28 $gp Global pointer - puntero a zona de memoria estástica. Debe ser salvado  
R29 $sp Stack Pointer - Puntero de pila. Debe ser salvado  
R30 $fp Frame Pointer - Puntero de pila. Debe ser salvado  
R31 $ra Return Addres - Dir. de retorno de subrutina. Debe ser salvado  

Ejercicio_6

.data
    VALOR1: .word 2
    VALOR2: .word 4
    RES:    .word 0
    
.text
    ld $a0, VALOR1($zero)   ; a = 16
    ld $a1, VALOR2($zero)   ; a1 = 4
    jal a_la_potencia       ; Salta y guarda la dir en R31
    sd $v0, RES($zero)      ; Muesto el valor de retorno de la subrutina
    halt

    a_la_potencia: daddi $v0, $zero, 1  ; Incremento v0
        lazo: slt $t1, $a1, $zero       ; si a1 < 0 deja un 1 en t1
        bnez $t1, terminar              ; cuando t1 llega a 0 termino
        daddi $a1, $a1, -1              ; decremento a1
        dmul $v0, $v0, $a0              ; v0 = v0 * a0
        j lazo

    terminar: jr $ra

    ; El programa saca la potencia de un nro, el programa hace VALOR2 ^ VALOR1

    ; jal Salta a la dirección rotulada offN y copia en r31 la dirección de retorno

    ; Salta a la dirección contenida en el registro rd

Ejercicio_7 ===========

.data
    M: .word 3
    TABLA: .word 1,2,3,4,5
    RESULTADO: .word 0
.code
    ld $a0, M(r0)           ; a0 = 14
    daddi $a1, $0, 5        ; a1 = cantidad de elementos
    daddi $a2, $0, TABLA    ; a2 = paso la direccion de TABLA
    jal VALORES             ; salto a la rutina y guardo la direccion de retorno
    nop                     ; pinto
    sd $v0, RESULTADO($0)   ; VALORES de retorno de la subrutina, lo guardo en RESULTADO
    halt

VALORES: dadd $t0, $a1, $0              ; guardo 5 en el registro temporal
    dadd $v0, $0, $0                    ; inicializo v0
    LOOP: ld $t4, 0($a2)                ; copia en el registro temporal el primer elemento de la TABLA
        slt $t2, $t4, $a0               ; si t4 es menor que a0, entonces dejo 1 en t2
        bnez $t2 ,NO_INCREMENTAR        ; si t2 <> 0 entonces salto a NO_INCREMENTAR
        beq $t4, $a0, NO_INCREMENTAR    ; Si es igual, no incremento
        daddi $v0, $v0, 1               ; aumento el contador 
    NO_INCREMENTAR: daddi $a2, $a2, 8   ; avanzo en la tabla
        daddi $t0, $t0, -1              ; decremento el contador de elementos de tabla
        bnez $t0, LOOP                  ; si t0 <> 0 salto a loop
        jr $ra                          ; vuelve al programa principal

Ejercicio_8 ===========

.data
    CADENA1: .asciiz "hola"
    CADENA2: .asciiz "holaa"
    result:  .word 0
.code
    daddi $a0, $0, CADENA1      ; a0 = CADENA1
    daddi $a1, $0, CADENA2      ; a1 = CADENA2
    jal compara                 ; Llamo a la subrutina
    sd $v0, result($zero)       ; guardo el valor
halt

compara: dadd $v0, $0, $0   ; inicializo V0
    LOOP: lbu $t0, 0($a0)   ; COPIA LA DIRECCION DE CADENA1
        lbu $t1, 0($a1)     ; COPIA LA DIRECCION DE CADENA2
        beqz $t0, FIN_CAD1  ; SI LLEGO AL FINAL DE CADENA1, SALTO
        beqz $t1, FIN       ; SI LLEGO AL FINAL DE CADENA2, SALTO
        bne $t0, $t1, FIN   ; SI EL CARACTER ACTUAL DE CADENA1 <> CARACTER ACTUAL CADENA2, TERMINO
        
        daddi $v0, $v0, 1       ; INCREMENTO
        daddi $a0, $a0, 1       ; INCREMENTO
        daddi $a1, $a1, 1       ; INCREMENTO
    j LOOP

    FIN_CAD1: bnez $t1, FIN     ; SI T1 <> 0, TERMINO
        daddi $v0, $0, -1
    FIN: jr $ra

Ejercicio_9 ===========

.data
    LETRA: .ascii '1'
    VOCALES: .asciiz 'AEIOUaeiou'
    RESULTADO: .word 0
.code
    lbu $a0, LETRA($0)          ; paso el CARACTER
    jal ES_VOCAL                ; llamo a la subrutina
    sd $v0, RESULTADO($zero)    ; guardo el resultado
halt

ES_VOCAL:   dadd $v0, $0, $0                ; inicializo v0
            daddi $t0, $0, 0                ; inicializo t0
            LOOP: lbu $t1, VOCALES($t0)     ; copia el  caracter en t1
                beqz $t1, FIN_VOCAL         ; si t1 = 0, no se encontro VOCALES
                beq $a0, $t1, ENCONTRO      ; si LETRA = caracterActual, salto
                daddi $t0, $t0, 1           ; continuo con el siguiente caracter
            j LOOP

            ENCONTRO: daddi $v0, $0, 1      ; si es vocal, retorno 1
            
            FIN_VOCAL: jr $ra               ;vuelvo al programa principal

Ejercicio_10 ============

.data
    CADENA: .asciiz "CazaAAA"
    VOCALES: .asciiz 'AEIOUaeiou'
    CANT: .word 0
.code
    ; La pila comienza en el tope de la memoria de datos
    DADDI $sp, $0, 0x400            ; bus 10 bits 🡪 2^10 = 1024 = 0x400

    ; Guarda como primer argumento para CONT_VOCALES
    ; la dirección de CADENA

    DADDI $a0, $0, CADENA
    dadd $v0, $0, $0  
    JAL CONT_VOCALES
    sd $v0, CANT($0)                  ; Cantidad de caracteres
HALT

CONT_VOCALES: DADDI $sp, $sp, -16     ; Reserva lugar en pila -> 2 x 8
    SD $ra, 0 ($sp)                   ; Guarda en pila $ra
    SD $s0, 8 ($sp)                   ; Guarda en pila $s0

    DADD $s0, $a0, $0                 ; Copia la dirección de inicio de la CADENA
    LOOP: LBU $a0, 0 ($s0)	        ; Toma car. actual
        BEQ $a0, $zero, FIN         ; Si es el fin, termina
        JAL ES_VOCAL
        DADDI $s0, $s0, 1           ; Avanza al siguiente caracter
    J LOOP

    ; Recupera los datos salvados en la pila
    FIN: LD $ra, 0 ($sp)
        LD $s0, 8 ($sp)
        DADDI $sp, $sp, 16
    JR $ra




ES_VOCAL: daddi $t0, $0, 0                    ; inicializo t0
    LOOP2: lbu $t1, VOCALES($t0)     ; copia el  caracter en t1
        beqz $t1, FINVOCAL         ; si t1 = 0, no se encontro VOCALES
        beq $a0, $t1, ENCONTRO      ; si LETRA = caracterActual, salto
        daddi $t0, $t0, 1           ; continuo con el siguiente caracter
    j LOOP2

    ENCONTRO: daddi $v0, $v0, 1      ; si es vocal, aumento 1 el contador
    FINVOCAL: jr $ra               ;vuelvo al programa principal             

Ejercicio_11 ============

.data
    TABLA: .word 1,2,3,4,5,0
    IMPARES: .word 0
    MASCARA: .byte 00000001
.code
    DADDI $sp, $0, 0x400
    DADDI $a0, $0, TABLA
    DADD $v0, $0, $0 
    
    JAL CONT_IMPAR
    sd $v0,IMPARES($0)
HALT

CONT_IMPAR: DADDI $sp, $sp, -16     
    SD $ra, 0 ($sp)                  
    SD $s0, 8 ($sp)
    DADD $s0, $a0, $0  
    
    LOOP: LD $a0, 0 ($s0)	        ; Toma nro. actual
        BEQ $a0, $0, FIN            ; Si es el fin, termina
        JAL ESIMPAR
        dadd $v0,$v0,$v1
        DADDI $s0, $s0, 8           ; Avanza al siguiente nro
    J LOOP

    FIN: LD $ra, 0 ($sp)
        LD $s0, 8 ($sp)
        DADDI $sp, $sp, 16
        JR $ra

ESIMPAR: LD $s1,MASCARA($0)      ;inicializo la mascara(como constante)
    AND $t1, $a0, $s1            ;valor actual and mascara
    BEQZ $t1 ,PAR 
    DADDI $v1,$0, 1
    J TERMINO
    PAR: DADDI $v1, $0, 0     
    TERMINO: JR $ra         

Ejercicio_12 ============

.data
    NRO: .word 10
    RESULTADO: .word 0
.code
    daddi $sp, $0, 0x400    ; Inicializa el puntero al tope de la pila
    ld $a0, NRO($0)         ; a0 = NRO
    jal FACTORIAL           ; Llamo a la subrutina
    sd $v0, RESULTADO($0)   ; Guardo el dato
halt

 
FACTORIAL: daddi $sp, $sp, -16      ; PUSH
    sd $ra, 0($sp)
    sd $s0, 8($sp)

    beqz $a0, FIN_RECURSIVO         ; Si nro - 1 = 0, termino
    dadd $s0, $0, $a0               ; Tomo el valor actual    
    daddi $a0, $a0, -1              ; nro = nro - 1

    jal FACTORIAL                   ; RECURSIVO
    dmul $v0, $v0, $s0              ; v0 * nro actual
    j FIN                           ; termino

    FIN_RECURSIVO: daddi $v0, $0, 1

    FIN: ld $s0, 8($sp)             ; POP
        ld $ra, 0($sp)
        daddi $sp, $sp, 16
    jr $ra 

💻Practica 6

Procesador RISC: utilizando la E/S

1) El siguiente programa produce la salida de un mensaje predefinido en la ventana Terminal del simulador WinMIPS64. Resolución

Teniendo en cuenta las condiciones de control del puerto de E/S (en el resumen anterior), modifique el programa de modo que el mensaje a mostrar sea ingresado por teclado en lugar de ser un mensaje fijo.

.data
    texto: .asciiz "Hola, Mundo!" ; El mensaje a mostrar
    CONTROL: .word32 0x10000
    DATA: .word32 0x10008
.text
    lwu $s0, DATA($zero)        ; $s0 = dirección de DATA
    daddi $t0, $zero, texto     ; $t0 = dirección del mensaje a mostrar
    sd $t0, 0($s0)              ; DATA recibe el puntero al comienzo del mensaje
    lwu $s1, CONTROL($zero)     ; $s1 = dirección de CONTROL
    daddi $t0, $zero, 6         ; $t0 = 6 -> función 6: limpiar pantalla alfanumérica
    sd $t0, 0($s1)              ; CONTROL recibe 6 y limpia la pantalla
    daddi $t0, $zero, 4         ; $t0 = 4 -> función 4: salida de una cadena ASCII
    sd $t0, 0($s1)              ; CONTROL recibe 4 y produce la salida del mensaje
    halt

2) Escriba un programa que utilice sucesivamente dos subrutinas: La primera, denominada ingreso, debe solicitar el ingreso por teclado de un número entero (de un dígito), verificando que el valor ingresado realmente sea un dígito. La segunda, denominada muestra, deberá mostrar en la salida estándar del simulador (ventana Terminal) el valor del número ingresado expresado en letras (es decir, si se ingresa un ‘4’, deberá mostrar ‘CUATRO’). Establezca el pasaje de parámetros entre subrutinas respetando las convenciones para el uso de los registros y minimice las detenciones del cauce (ejercicio similar al ejercicio 6 de Práctica 2). Resolución

3) Escriba un programa que realice la suma de dos números enteros (de un dígito cada uno) utilizando dos subrutinas: La denominada ingreso del ejercicio anterior (ingreso por teclado de un dígito numérico) y otra denominada resultado, que muestre en la salida estándar del simulador (ventana Terminal) el resultado numérico de la suma de los dos números ingresados (ejercicio similar al ejercicio 7 de Práctica 2). Resolución

4) Escriba un programa que solicite el ingreso por teclado de una clave (sucesión de cuatro caracteres) utilizando la subrutina char de ingreso de un carácter. Luego, debe comparar la secuencia ingresada con una cadena almacenada en la variable clave. Si las dos cadenas son iguales entre si, la subrutina llamada respuesta mostrará el texto “Bienvenido” en la salida estándar del simulador (ventana Terminal). En cambio, si las cadenas no son iguales, la subrutina deberá mostrar “ERROR” y solicitar nuevamente el ingreso de la clave. Resolución

5) Escriba un programa que calcule el resultado de elevar un valor en punto flotante a la potencia indicada por un exponente que es un número entero positivo. Para ello, en el programa principal se solicitará el ingreso de la base (un número en punto flotante) y del exponente (un número entero sin signo) y se deberá utilizar la subrutina a_la_potencia para calcular el resultado pedido (que será un valor en punto flotante). Tenga en cuenta que cualquier base elevada a la 0 da como resultado 1. Muestre el resultado numérico de la operación en la salida estándar del simulador (ventana Terminal). Resolución

6) El siguiente programa produce una salida estableciendo el color de un punto de la pantalla gráfica (en la ventana Terminal del simulador WinMIPS64). Modifique el programa de modo que las coordenadas y color del punto sean ingresados por teclado. Resolución

data
    coorX: .byte 24                 ; coordenada X de un punto
    coorY: .byte 24                 ; coordenada Y de un punto
    color: .byte 255, 0, 255, 0     ; color: máximo rojo + máximo azul => magenta
    CONTROL: .word32 0x10000
    DATA: .word32 0x10008
.text
    lwu $s6, CONTROL($zero)         ; $s6 = dirección de CONTROL
    lwu $s7, DATA($zero)            ; $s7 = dirección de DATA
    daddi $t0, $zero, 7             ; $t0 = 7 -> función 7: limpiar pantalla gráfica
    sd $t0, 0($s6)                  ; CONTROL recibe 7 y limpia la pantalla gráfica
    lbu $s0, coorX($zero)           ; $s0 = valor de coordenada X
    sb $s0, 5($s7)                  ; DATA+5 recibe el valor de coordenada X
    lbu $s1, coorY($zero)           ; $s1 = valor de coordenada Y
    sb $s1, 4($s7)                  ; DATA+4 recibe el valor de coordenada Y
    lwu $s2, color($zero)           ; $s2 = valor de color a pintar
    sw $s2, 0($s7)                  ; DATA recibe el valor del color a pintar
    daddi $t0, $zero, 5             ; $t0 = 5 -> función 5: salida gráfica
    sd $t0, 0($s6)                  ; CONTROL recibe 5 y produce el dibujo del punto
    halt

7) Se desea realizar la demostración de la transformación de un carácter codificado en ASCII a su visualización en una matriz de puntos con 7 columnas y 9 filas. Escriba un programa que realice tal demostración, solicitando el ingreso por teclado de un carácter para luego mostrarlo en la pantalla gráfica de la terminal. Resolución

El “8” se representa como:

image

8) El siguiente programa implementa una animación de una pelotita rebotando por la pantalla. Modifíquelo para que en lugar de una pelotita, se muestren simultáneamente varias pelotitas (cinco, por ejemplo), cada una con su posición, dirección y color particular. Resolución

.data
    CONTROL: .word32 0x10000
    DATA: .word32 0x10008
    color_pelota: .word32 0x00FF0000        ; Azul
    color_fondo: .word32 0x00FFFFFF         ; Blanco
.text
    lwu $s6, CONTROL($zero)
    lwu $s7, DATA($zero)
    lwu $v0, color_pelota($zero)
    lwu $v1, color_fondo($zero)
    daddi $s0, $zero, 23                    ; Coordenada X de la pelota
    daddi $s1, $zero, 1                     ; Coordenada Y de la pelota
    daddi $s2, $zero, 1                     ; Dirección X de la pelota
    daddi $s3, $zero, 1                     ; Dirección Y de la pelota
    daddi $s4, $zero, 5                     ; Comando para dibujar un punto

loop: sw $v1, 0($s7) ; Borra la pelota
    sb $s0, 4($s7)
    sb $s1, 5($s7)
    sd $s4, 0($s6)
    dadd $s0, $s0, $s2                      ;Mueve la pelota en la dirección actual
    dadd $s1, $s1, $s3
    daddi $t1, $zero, 48                    ; Comprueba que la pelota no esté en la columna de más
    slt $t0, $t1, $s0                       ; a la derecha. Si es así, cambia la dirección en X.
    dsll $t0, $t0, 1
    dsub $s2, $s2, $t0
    slt $t0, $t1, $s1                       ; Comprueba que la pelota no esté en la fila de más arriba.
    dsll $t0, $t0, 1                        ; Si es así, cambia la dirección en Y.
    dsub $s3, $s3, $t0
    slti $t0, $s0, 1                        ; Comprueba que la pelota no esté en la columna de más
    dsll $t0, $t0, 1                        ; a la izquierda. Si es así, cambia la dirección en X.
    dadd $s2, $s2, $t0
    slti $t0, $s1, 1                        ; Comprueba que la pelota no esté en la fila de más abajo.
    dsll $t0, $t0, 1                        ; Si es así, cambia la dirección en Y.
    dadd $s3, $s3, $t0
    sw $v0, 0($s7)                          ; Dibuja la pelota.
    sb $s0, 4($s7)
    sb $s1, 5($s7)
    sd $s4, 0($s6)
    daddi $t0, $zero, 500                   ; Hace una demora para que el rebote no sea tan rápido.
demora: daddi $t0, $t0, -1                  ; Esto genera una infinidad de RAW y BTS pero...
    bnez $t0, demora                        ; ¡hay que hacer tiempo igualmente!
    j loop

9) Escriba un programa que le permita dibujar en la pantalla gráfica de la terminal. Deberá mostrar un cursor (representado por un punto de un color particular) que pueda desplazarse por la pantalla usando las teclas ‘a’, ‘s’, ‘d’ y ‘w’ para ir a la izquierda, abajo, a la derecha y arriba respectivamente. Usando la barra espaciadora se alternará entre modo desplazamiento (el cursor pasa por arriba de lo dibujado sin alterarlo) y modo dibujo (cada punto por el que el cursor pasa quedará pintado del color seleccionado). Las teclas del ‘1’ al ‘8’ se usarán para elegir uno entre los ocho colores disponibles para pintar. Resolución

Observaciones: Para poder implementar este programa, se necesitará almacenar en la memoria la imagen completa de la pantalla gráfica.

Si cada punto está representado por un byte, se necesitarán 50x50x1 = 2500 bytes. El simulador WinMIPS64 viene configurado para usar un bus de datos de 10 bits, por lo que la memoria disponible estará acotada a 2^10=1024 bytes. Para poder almacenar la imagen, será necesario configurar el simulador para usar un bus de datos de 12 bits, ya que 2^12=4096 bytes, los que si resultarán suficientes. La configuración se logra yendo al menú “Configure -> Architecture” y poniendo “Data Address Bus” en 12 bits en lugar de los 10 bits que trae por defecto.

image

Ejercicio_1

.data
    CONTROL: .word 0x10000
    DATA:    .word 0x10008
    CARACTER: .byte 0
.code
    LWU $s0, CONTROL($0)
    LWU $s1, DATA($0)
    
    DADDI $s4, $0, 13       ; 13 el ascii del enter 

    LOOP: DADDI $t1, $0, 9
        SD $t1,0 ($s0)      ; CONTROL = 9

        ; *PRESIONA UNA TECLA*
        ; LA CPU GUARDA EL CARACTER EN DATA

        LBU $t1,0 ($s1)

        ; COMPARO CON EL ENTER
        BEQ $t1, $s4, FIN

        ; GUARDO LA VARIABLE
        SB $t1, CARACTER($0)

        ;TOMO LA DIR DE CARACTER
        DADDI $s3, $0, CARACTER

        ; MANDO DIR DE CARACTER
        SD $s3, 0 ($s1)

        ; IMPRIMIR CARACTER
        DADDI $t1, $0, 4
        SD $t1, 0 ($s0) ; CONTROL 4

        J LOOP
FIN: HALT

Ejercicio_2

.data ;leer desde teclado
    CONTROL:      .word 0x10000
    DATA:         .word 0x10008
    MENSAJE:      .asciiz " INGRESE UN CARACTER: "
    MENSAJEMAL:  .asciiz "  EL CARACTER NO ES UN DIGITO. "
    CERO:         .asciiz " CERO  "
    UNO:          .asciiz " UNO   "
    DOS:          .asciiz " DOS   "
    TRES:         .asciiz " TRES  "
    CUATRO:       .asciiz " CUATRO"
    CINCO:        .asciiz " CINCO "
    SEIS:         .asciiz " SEIS  "
    SIETE:        .asciiz " SIETE "
    OCHO:         .asciiz " OCHO  "
    NUEVE:        .asciiz " NUEVE "
    CARACTER: .byte 0
.code
    LWU $s0, CONTROL ($0) 	; $s0 = CONTROL
    LWU $s1, DATA ($0) 	   	; $s1 = DATA
    ;_______________________________    IMPRIME MENSAJE
    DADDI $t0, $0, MENSAJE  
    SD $t0, 0($s1)        
    DADDI $t0, $0, 4        
    SD $t0, 0($s0)          
    ;_______________________________
    DADDI $sp, $0, 0x400        ; INICIALIZO EL PUNTERO A TOPE DE PILA
    JAL INGRESO
    LD $t0, CARACTER($0) 
    SLTI $t1, $t0, 0x30         ; un 1 si es menor
    DADDI $t3, $t3, 0x39
    SLT $t1, $t3,  $t0         ; un 1 si me paso
    DADDI $t4, $t4 ,1
    BEQ $t1, $t4 , MALO
    
    DADDI $a1, $0, CERO
    JAL MUESTRA
    J TERMINO
    
    
    
    MALO: DADDI $t0, $0, MENSAJEMAL  
    SD $t0, 0($s1)        
    DADDI $t0, $0, 4        
    SD $t0, 0($s0)   

    TERMINO: HALT


INGRESO: DADDI $sp, $sp, -8 
    SD $t7, 0 ($sp)
    ;______________________________
    DADDI $t1, $0, 9   ; LEE UN CARACTER
    SD $t1,0 ($s0)
    LBU $t1,0 ($s1)
    SB $t1, CARACTER($0)
    ; IMPRIME
    DADDI $s3, $0, CARACTER
    SD $s3, 0 ($s1)
    DADDI $t1, $0, 4
    SD $t1, 0 ($s0) 
    ;_______________________________  LEE E IMPRIME EL CARACTER
    LD $t7, 0 ($sp)
    DADDI $sp, $sp, 8  
    JR $ra

MUESTRA:  daddi $t7,$0,0x30
    LOOP: BEQ $t0, $t7, IMPRIMIR
        DADDI $t0, $t0, -1
        DADDI $a1, $a1, 8
        J LOOP

    IMPRIMIR:  SD $a1, 0($s1)        
    DADDI $t1, $0, 4        
    SD $t1, 0($s0)    
JR $ra

Ejercicio_3 ===========

.data ;leer desde teclado
    CONTROL:      .word 0x10000
    DATA:         .word 0x10008
    MENSAJE:      .asciiz "INGRESE UN NRO: "
    MENSAJE2:     .asciiz "EL RESULTADO ES: "
    RES: .word 0
    NRO: .byte 0
.code
    LWU $s0, CONTROL ($0) 	; $s0 = CONTROL
    LWU $s1, DATA ($0) 	   	; $s1 = DATA
    ;_______________________________    IMPRIME MENSAJE
    DADDI $t0, $0, MENSAJE  
    SD $t0, 0($s1)        
    DADDI $t0, $0, 4        
    SD $t0, 0($s0)          
    ;_______________________________
    DADDI $sp, $0, 0x400        ; INICIALIZO EL PUNTERO A TOPE DE PILA

    JAL INGRESO   

    LD $t6, NRO($0)
    

    DADDI $t0, $0, MENSAJE  
    SD $t0, 0($s1)        
    DADDI $t0, $0, 4        
    SD $t0, 0($s0) 
    
    JAL INGRESO   
    LD $t7, NRO($0)
    
    DADD $t6, $t6, $t7
    

    JAL RESULTADO
    HALT


INGRESO: DADDI $sp, $sp, -8 
    SD $t7, 0 ($sp)
    ;______________________________
    DADDI $t1, $0, 8   ; LEE UN NRO
    SD $t1,0 ($s0)
    LBU $t1,0 ($s1)
    SB $t1, NRO($0)
    ; IMPRIME
    DADDI $s3, $0, NRO
    SD $s3, 0 ($s1)
    DADDI $t1, $0, 4
    SD $t1, 0 ($s0) 
    ;_______________________________  LEE E IMPRIME EL NRO
    LD $t7, 0 ($sp)
    DADDI $sp, $sp, 8  
    JR $ra

RESULTADO: DADDI $t0, $0, MENSAJE2  
    SD $t0, 0($s1)        
    DADDI $t0, $0, 4        
    SD $t0, 0($s0)    

    DADDI $t6, $t6 , 0x30   ; PARA IMPRIMIR EL ASCII DEL NRO
    SD $t6, RES ($0)  

    DADDI $s3, $0, RES
    SD $s3, 0 ($s1)
    DADDI $t1, $0, 4
    SD $t1, 0 ($s0) 

    JR $ra

Ejercicio_4

.data 
    CONTROL:       .word 0x10000
    DATA:          .word 0x10008
    CONTRA:        .asciiz 'VAMOO'
    ERROR:         .asciiz ' ERROR!'
    CORRECTO:      .asciiz ' BIENVENIDO'
    MENSAJE:       .asciiz 'INGRESE UNA CONTRA: '
    CARACTER:      .byte 0
.code
    LWU $s0, CONTROL($0)
    LWU $s1, DATA($0)
    DADDI $t0, $0, MENSAJE  
    SD $t0, 0($s1)        
    DADDI $t0, $0, 4        
    SD $t0, 0($s0) 
    
    DADDI $sp, $0, 0x400
    JAL CHAR
HALT


CHAR: daddi $t6, $0, 0           ;CONTADOR PARA CARACTERES
    LOOP: DADDI $t1, $0, 9
        SD $t1,0 ($s0)      ; CONTROL = 9

        
        ; *PRESIONA UNA TECLA*
        ; LA CPU GUARDA EL CARACTER EN DATA

        LBU $t1,0 ($s1)

        DADD $t7, $0, $t1       ;MANDO MI CARACTER A UN REGISTRO PARA COMPARAR
        ; GUARDO LA VARIABLE
        SB $t1, CARACTER($0)

        ;TOMO LA DIR DE CARACTER
        DADDI $s3, $0, CARACTER

        ; MANDO DIR DE CARACTER
        SD $s3, 0 ($s1)

        lbu $t5, CONTRA($t6)    ;GUARDO EN T5 EL CARACTER ACTUAL DE CONTRA
        beqz $t5, FIN_BIEN           ; INDICA QUE TERMINO LA CONTRA (QUE TERMINO BIEN)
        BNE $t1, $t5, FIN_MAL

        ; IMPRIMIR CARACTER
        DADDI $t1, $0, 4
        SD $t1, 0 ($s0) ; CONTROL 4
        daddi $t6, $t6, 1           ;AVANZO AL SIGUIENTE CARACTER DE MI CONTRA
        J LOOP

        FIN_BIEN: DADDI $t0, $0, CORRECTO  ;IMPRIMO CORRECTO
            SD $t0, 0($s1)        
            DADDI $t0, $0, 4        
            SD $t0, 0($s0)   
            J FIN
        FIN_MAL: DADDI $t0, $0, ERROR  ;IMPRIMO CORRECTO
            SD $t0, 0($s1)        
            DADDI $t0, $0, 4        
            SD $t0, 0($s0)   
            J FIN

    FIN: JR $ra

Ejercicio_5 ===========

.data ;leer desde teclado
    CONTROL:    .word 0x10000
    DATA:       .word 0x10008
    BASE:       .double 0.0
    EXPONENTE:       .word 0
    MENSAJE:    .asciiz "BASE (FLOTANTE): "
    MENSAJE2:    .asciiz "EXPONENTE (ENTERO): "
    RES: .double 0
    UNO: .double 1.0

.code
    LWU $s0, CONTROL ($zero) 	; $s0 = CONTROL
    LWU $s1, DATA ($zero) 	   	; $s1 = DATA

    DADDI $t0, $0, MENSAJE  
    SD $t0, 0($s1)        
    DADDI $t0, $0, 4        
    SD $t0, 0($s0)   

    DADDI $t0, $zero, 8
    SD $t0, 0 ($s0)             ; CONTROL = 8
    L.D f1, 0 ($s1)             ; Tomo número en f1
    S.D f1, BASE ($zero)        ; Guardo en variable

    DADDI $t0, $0, MENSAJE2  
    SD $t0, 0($s1)        
    DADDI $t0, $0, 4        
    SD $t0, 0($s0)   

    DADDI $t0, $zero, 8
    SD $t0, 0 ($s0)                 ; CONTROL = 8
    LD $t1, 0 ($s1)                 ; Tomo número en t0
    SD $t1, EXPONENTE ($zero)       ; Guardo en variable

    JAL POTENCIA
    S.D f2, RES($0)
  
    S.D f2, 0 ($s1)
    ; Control 3
    DADDI $t0, $0, 3
    SD $t0, 0 ($s0)               
HALT

POTENCIA: L.D f2, UNO($0)
    LOOP: BEQZ $t1, FIN
        mul.d f2, f2, f1
        DADDI $t1, $t1, -1    
    J LOOP

    FIN: jr $ra

Ejercicio_6

.data
    coorX:      .byte 0
    coorY:      .byte 0
    color:      .byte 0, 0, 0, 0; 
    CONTROL:    .word32 0x10000
    DATA:       .word32 0x10008
    MENSAJE1:   .asciiz "INGRESE X: "
    MENSAJE2:   .asciiz "INGRESE Y: "
    MENSAJE3:   .asciiz "INGRESE (R,G,B,TRANSPARENCIA) : "

.code
    LWU $s6, CONTROL($zero)
    LWU $s7, DATA($zero)
    ;__________________________________
    DADDI $t0, $0, MENSAJE1 
    SD $t0, 0 ($s7) 
    DADDI $t1, $0, 4 
    SD $t1, 0 ($s6) 

    DADDI $t1, $0, 8
    SB $t1, 0($s6) 
    LBU $t2, 0($s7) 
    SB $t2, coorX($0)
    ;__________________________________    
    DADDI $t0, $0, MENSAJE2 
    SD $t0, 0 ($s7) 
    DADDI $t1, $0, 4 
    SD $t1, 0 ($s6) 
    
    DADDI $t1, $0, 8
    SB $t1, 0($s6) 
    LBU $t3, 0($s7) 
    SB $t3, coorY($0)
    ;__________________________________
    DADDI $t0, $0, MENSAJE3
    SD $t0, 0 ($s7)
    DADDI $t1, $0, 4 
    SD $t1, 0 ($s6)

    DADDI $a0, $0, 0    ;CONTADORES PARA LEER
    DADDI $a1, $0, 3
    
    LOOP: DADDI $t1, $0, 8
        SB $t1, 0($s6) 
        LBU $t3, 0($s7) 
        SB $t3, color($a0)
        DADDI $a0, $a0, 1   ;AVANZO AL SIGUIENTE BYTE
    bne $a0, $a1 ,LOOP
    ;__________________________________
    DADDI $t0, $zero, 7
    SD $t0, 0($s6)
    
    LBU $s0, coorX($zero)
    SB $s0, 5($s7)

    LBU $s1, coorY($zero)
    SB $s1, 4($s7)

    LWU $s2, color($zero)
    sw $s2, 0($s7)
    
    DADDI $t0, $zero, 5
    SD $t0, 0($s6)         
HALT

Ejercicio_7 ===========

Ejercicio_8

.data
    CONTROL: .word32 0x10000
    DATA: .word32 0x10008
    fondo: .word32 0x00FFFFFF   ; Blanco

    pelota1: .word32 0x00FF0000 ; Azul
             .byte 23           ; Pos X
             .byte 1            ; Pos Y
             .word 1            ; Direccion X
             .word 1            ; Direccion Y
    pelota2: .word32 0x0000FF00
             .byte 27           ; Pos X
             .byte 21           ; Pos Y
             .word -1           ; Direccion X
             .word -1           ; Direccion Y
    pelota3: .word32 0x000000FF
             .byte 1            ; Pos X
             .byte 5            ; Pos Y
             .word 1            ; Direccion X
             .word 1            ; Direccion Y
    pelota4: .word32 0x00FF00FF
             .byte 35           ; Pos X
             .byte 35           ; Pos Y
             .word -1           ; Direccion X
             .word 1            ; Direccion Y
    pelota5: .word32 0x00FFFF00
             .byte 1            ; Pos X
             .byte 35           ; Pos Y
             .word 1            ; Direccion X
             .word 1            ; Direccion Y
    pelota6: .word32 0x0000FFFF
             .byte 35           ; Pos X
             .byte 1            ; Pos Y
             .word -1           ; Direccion X
             .word 1            ; Direccion Y
 .code
    daddi $sp, $0, 0x400
    loop: daddi $a0, $zero, pelota1
        jal mostrar
        daddi $a0, $zero, pelota2
        jal mostrar
        daddi $a0, $zero, pelota3
        jal mostrar
        daddi $a0, $zero, pelota4
        jal mostrar
        daddi $a0, $zero, pelota5
        jal mostrar
        daddi $a0, $zero, pelota6
        jal mostrar
        daddi $t0, $0, 500              ; Hace una demora para que el rebote no sea tan rápido.
        demora: daddi $t0, $t0, -1      ; Esto genera una infinidad de RAW y BTS pero...
        bnez $t0, demora                ; hay que hacer tiempo igualmente!
 j loop

;__________________________________
mostrar: daddi $sp, $sp, -16
    sd $s0, 0($sp)
    sd $s1, 8($sp)
    lwu $s0, CONTROL($0)
    lwu $s1, DATA($0)
    lwu $t0, fondo($zero)       ; Recupero fondo
    lwu $t1, 0($a0)             ; Recupero color
    lbu $t2, 8($a0)             ; Recupero Coordenada X de la pelota
    lbu $t3, 16($a0)            ; Recupero Coordenada Y de la pelota
    ld $t4, 24($a0)             ; Recupero Dirección X de la pelota
    ld $t5, 32($a0)             ; Recupero Dirección Y de la pelota
    daddi $t6, $0, 5            ; Comando para dibujar un punto
    
    ; Borra la pelota
    sw $t0, 0($s1)          ; Color de Fondo
    sb $t2, 4($s1)          ; Pos X
    sb $t3, 5($s1)          ; Pos Y
    sd $t6, 0($s0)          ; Dibujar
    dadd $t2, $t2, $t4      ; Mueve la pelota en la dirección actual
    dadd $t3, $t3, $t5
    daddi $t7, $0, 48       ; Comprueba que la pelota no está en la columna de más
    slt $t8, $t7, $t2       ; a la derecha. Si es así, cambia la dirección en X.
    dsll $t8, $t8, 1
    dsub $t4, $t4, $t8
    slt $t8, $t7, $t3       ; Comprueba que la pelota no está en la fila
    ; de más arriba.
    dsll $t8, $t8, 1        ; Si es así, cambia la dirección en Y.
    dsub $t5, $t5, $t8
    slti $t8, $t2, 1        ; Comprueba que la pelota no está en la columna de más
    dsll $t8, $t8, 1        ; a la izquierda. Si es así, cambia la dirección en X.
    dadd $t4, $t4, $t8
    slti $t8, $t3, 1        ; Comprueba que la pelota no está en la fila de más
    dsll $t8, $t8, 1        ; abajo. Si es así, cambia la dirección en Y.
    dadd $t5, $t5, $t8

    sw $t1, 0($s1)          ; Dibuja la pelota.
    sb $t2, 4($s1)
    sb $t3, 5($s1)
    sd $t6, 0($s0)

    sb $t2, 8($a0)          ; Guardo Coordenada X de la pelota
    sb $t3, 16($a0)         ; Guardo Coordenada Y de la pelota
    sd $t4, 24($a0)         ; Guardo Dirección X de la pelota
    sd $t5, 32($a0)         ; Guardo Dirección Y de la pelota
    ld $s0, 0($sp)
    ld $s1, 8($sp)
    daddi $sp, $sp, 16
    jr $ra

Ejercicio_9

.data
        CONTROL: .word32  0x10000
        DATA:    .word32  0x10008
        MENU:    .asciiz "  Reset    (0)\n  NEGRO    (1)\n  AZUL     (2)\n  VERDE    (3)\n  CYAN     (4)\n  ROJO     (5)\n  VIOLETA  (6)\n  AMARILLO (7)\n  BLANCO   (8)\n  ACTUAL: "

        NEGRO:          .byte    0,  0,  0,  0     
        AZUL:           .byte    0,  0,  255,0     
        VERDE:          .byte    0,  255,0,  0     
        CYAN:           .byte    0,  255,255,0     
        ROJO:           .byte    255,0,  0,  0     
        VIOLETA:        .byte    255,0,  255,0   
        AMARILLO:       .byte    255,255,0,  0     
        BLANCO:         .byte    255,255,255,0     
        GRIS:           .byte    150,150,150,0    
                                
        NEGROCAR:       .asciiz  "NEGRO"          
        AZULCAR:        .asciiz  "AZUL"            
        VERDECAR:       .asciiz  "VERDE"          
        CYANCAR:        .asciiz  "CYAN"            
        ROJOCAR:        .asciiz  "ROJO"            
        VIOLETACAR:     .asciiz  "VIOLETA"         
        AMARILLOCAR:    .asciiz  "AMARILLO"         
        BLANCOCAR:      .asciiz  "BLANCO"                                     
        IMAGE:          .space   2500             
        OFF:            .space   1                

.code                      
        DADDI  $sp, $0, 0x400    
        DADDI  $v1, $0, 1         
        DADDI  $s1, $0, 5          
        DADDI  $s2, $0, 7         
        DADDI  $s3, $0, 9         
        DADDI  $s4, $0, 50       ;LIMITE     
        DADDI  $s0, $0, GRIS      
        DADDI  $s5, $0, NEGRO  

        DADDI  $s6, $0, 24         
        DADDI  $s7, $0, 24        
        DADDI  $t2, $0, 24         
        DADDI  $t3, $0, 24         

        LWU    $t8, DATA($0)       
        LWU    $t9, CONTROL($0)    

LIMPIAR: DADDI  $t0, $0, IMAGE      
         DADDI  $t1, $0, OFF        
         DADDI  $t3, $0, BLANCO      
INICIAR: SB     $t3, 0($t0)         
         DADDI  $t0, $t0, 1        
         BNE    $t0, $t1, INICIAR   

         JAL    IMPRIMIRMENU            
LEER:    JAL    DIBUJARPIXEL             
         JAL    DIBUJARESQUINA             
         SD     $s3, 0($t9)         
         LB     $t0, 0($t8)         
;____________________________________________________________
ARRIBA: DADDI  $v0, $0, 0x57                            ; W
        BNE    $t0, $v0, ARRIBA2       
        J MAXARRIBA             

ARRIBA2: DADDI  $v0, $0, 0x77                           ; w
         BNE    $t0, $v0, DERECHA       
         J MAXARRIBA             

DERECHA: DADDI  $v0, $0, 0x44                           ; D
         BNE    $t0, $v0, DERECHA2       
         J MAXDERECHA             

DERECHA2: DADDI  $v0, $0, 0x64                          ; d
          BNE $t0, $v0, IZQUIERDA       
          J MAXDERECHA             

IZQUIERDA: DADDI  $v0, $0, 0x41                         ; A
           BNE $t0, $v0, IZQUIERDA2       
           J MAXIZQUIRDA             

IZQUIERDA2: DADDI  $v0, $0, 0x61                        ; a
            BNE    $t0, $v0, ABAJO       
            J MAXIZQUIRDA             

ABAJO: DADDI  $v0, $0, 0x53                             ; S
       BNE    $t0, $v0, ABAJO2       
       J MAXABAJO              

ABAJO2: DADDI  $v0, $0, 0x73                            ; s
        BNE    $t0, $v0, ESPACIO     
        J MAXABAJO             
;____________________________________________________________
ESPACIO: DADDI  $v0, $0, 0x20                   ; ESPACIO
         BNE    $t0, $v0, REINICIAR             ; t0 <> 
         BEQ    $v1, $0, CONCEDIDO       
DENEGAR: DADDI  $v1, $0, 0          
         J LEER                
CONCEDIDO: DADDI  $v1, $0, 1          
           J LEER               

REINICIAR: DADDI  $v0, $0, 0x30                 ; 0
           BNE    $t0, $v0, CONEGRO   
           DADDI  $t0, $0, 7          
           SD     $t0, 0($t9)        
           DADDI  $v1, $0, 1          
           J LIMPIAR             
;____________________________________________________________COLORES
CONEGRO: DADDI  $v0, $0, 0x31                   ; 1
         BNE    $t0, $v0, COAZUL     
         DADDI  $s5, $0, NEGRO       
         JAL IMPRIMIRMENU            
         J LEER                

COAZUL: DADDI  $v0, $0, 0x32                    ; 2       
        BNE    $t0, $v0, COVERDE     
        DADDI  $s5, $0, AZUL       
        JAL IMPRIMIRMENU             
        J LEER                

COVERDE: DADDI  $v0, $0, 0x33                   ; 3
         BNE    $t0, $v0, COCYAN     
         DADDI  $s5, $0, VERDE       
         JAL    IMPRIMIRMENU             
         J LEER                

COCYAN: DADDI  $v0, $0, 0x34                    ; 4
        BNE    $t0, $v0, COROJO     
        DADDI  $s5, $0, CYAN       
        JAL    IMPRIMIRMENU            
        J LEER                

COROJO: DADDI  $v0, $0, 0x35                    ; 5
        BNE    $t0, $v0, COVIOLETA    
        DADDI  $s5, $0, ROJO       
        JAL    IMPRIMIRMENU             
        J LEER                

COVIOLETA: DADDI  $v0, $0, 0x36                 ; 6
           BNE    $t0, $v0, COAMARILLO     
           DADDI  $s5, $0, VIOLETA       
           JAL    IMPRIMIRMENU             
           J LEER                

COAMARILLO: DADDI  $v0, $0, 0x37                ; 7
            BNE    $t0, $v0, COBLANCO     
            DADDI  $s5, $0, AMARILLO       
            JAL    IMPRIMIRMENU             
            J LEER                

COBLANCO: DADDI  $v0, $0, 0x38                  ; 8
          BNE    $t0, $v0, LEER      
          DADDI  $s5, $0, BLANCO       
          JAL    IMPRIMIRMENU             
          J LEER               
;____________________________________________________________
MAXARRIBA: BEQ    $s7, $s4, LEER      
           DADD   $t2, $s6, $0        
           DADD   $t3, $s7, $0        
           DADDI  $s7, $s7, 1         
           J LEER                

MAXDERECHA: BEQ    $s6, $s4, LEER      
            DADD   $t2, $s6, $0        
            DADD   $t3, $s7, $0        
            DADDI  $s6, $s6, 1         
         J LEER                


MAXABAJO:  BEQZ   $s7, LEER          
         DADD   $t2, $s6, $0        
         DADD   $t3, $s7, $0        
         DADDI  $s7, $s7, -1        
         J      LEER               

MAXIZQUIRDA: BEQZ   $s6, LEER           
         DADD   $t2, $s6, $0        
         DADD   $t3, $s7, $0        
         DADDI  $s6, $s6, -1        
         J      LEER                
;____________________________________________________________
DIBUJARPIXEL: BNEZ   $v1, PINCEL  ; SI = 1 , VOY A PINCEL      
              LBU    $t0, 0($s5)         
              SB     $t2, 5($t8)         
              SB     $t3, 4($t8)         
              DADDI  $t0, $t0, -8        
              LWU    $t0, 0($s0)        
              SW     $t0, 0($t8)        
              SD     $t1, 0($t9)        
              JR     $ra         
                 
PINCEL: DMUL   $t0, $t2, $s4       
        SB     $t2, 5($t8)         
        SB     $t3, 4($t8)        
        DADD   $t0, $t0, $t3       
        DADDI  $t0, $t0, IMAGE     
        LBU    $t0, 0($t0)         
        DADDI  $t0, $t0, -8        
        LWU    $t0, 0($t0)         
        SW     $t0, 0($t8)         
        SD     $s1, 0($t9)         
        JR     $ra                

DIBUJARESQUINA: SB     $s6, 5($t8)        
                SB     $s7, 4($t8)         
                BEQZ   $v1, COPINCEL        
                DADDI  $t0, $0, CYAN            ; QUE COLOR DE TROLO
                J      COCURSOR  
                           
COPINCEL: DMUL   $t1, $s6, $s4       
          DADD   $t0, $0, $s5        
          DADD   $t1, $t1, $s7       
          DADDI  $t1, $t1, IMAGE     
          SB     $s5, 0($t1)    

COCURSOR: DADDI  $t0, $t0, -8        
          LWU    $t0, 0($t0)         
          SW     $t0, 0($t8)         
          SD     $s1, 0($t9)         
          JR     $ra                 

IMPRIMIRMENU: DADDI  $t0, $0, 6          
              SD     $t0, 0($t9)         
              DADDI  $t0, $0, MENU       
              SD     $t0, 0($t8)         
              DADDI  $t0, $0, 4          
              SD     $t0, 0($t9)         
              DADD   $t0, $0, $s5        
              DADDI  $t0, $t0, 64       
              SD     $t0, 0($t8)         
              DADDI  $t0, $0, 4          
              SD     $t0, 0($t9)         
              JR     $ra