![]() |
|
Duración: | 2 horas 15 minutos |
Puntuación: | 76 puntos (sobre 100) |
Fecha: | 26 de junio de 2003 |
Nota: | Se podrán usar libros y apuntes. |
Un programa escrito en ensamblador gestiona las localidades libres y ocupadas de un teatro. Cada localidad está representada mediante un bit. Si el valor es 1 dicha localidad está ocupada, y en caso contrario, está libre. Se asume que el aforo del teatro es múltiplo de 32.
Se pide escribir las siguientes rutinas. Todas ellas deben incluir el bloque de activación perfectamente construido. La solución debe estar comentada. Una solución sin comentarios se considerará incorrecta.
Nota: La instrucción ensamblador SAR desplaza el contenido de su destino tantas posiciones en bits hacia la derecha como indica su primer operando. El primer operando puede ser o un inmediato o el registro %cl, mientras que el segundo operando puede ser una posición de memoria o un registro.
Rutina cuentaunos que recibe como parámetro a través de la pila un número de 32 bits y devuelve como resultado a través del registro %eax el número de bits que están a uno en dicho número.
Solución:cuentaunos: push %ebp mov %esp, %ebp push %ebx push %ecx mov $0, %eax mov $0, %ebx mov 8(%ebp), %ecx cuentabucle: cmp $32, %ebx jge cuentafin inc %ebx test $0x00000001, %ecx jz nocuenta inc %eax nocuenta: sar $1, %ecx jmp cuentabucle cuentafin: pop %ecx pop %ebx pop %ebp ret
Rutina aforototal que recibe como parámetros el número de palabras de memoria de 32 bits que ocupa la representación del aforo y la dirección de memoria a partir de la cual está almacenada (introducidos en la pila en este orden) tal y como indica la siguiente figura.
La rutina devuelve como resultado en el registro %eax el número total de localidades ocupadas. La solución debe invocar la rutina del apartado anterior.
Solución:aforototal: push %ebp mov %esp, %ebp push %ebx # Se salvan los registros push %ecx push %edx mov 8(%ebp), %ebx # Ebx tiene la @ base de la tabla mov $0, %ecx # Ecx acumula los resultados mov $0, %edx # Edx es el indice para recorrer la tabla bucletotal: cmp 12(%ebp), %edx # Compara el índice con el tamaño de la tabla jge terminatotal # Si este último es mayor o igual se termina push (%ebx, %edx, 4) # Colocar el dato de la tabla en la pila call cuentaunos # Contar el número de unos add $4, %esp # Restaurar la pila add %eax, %ecx # Acumular el resultado en eax inc %edx # Incrementar el índice de la tabla jmp bucletotal # Salto de nuevo a la comparación terminatotal: mov %ecx, %eax # Mover el resultado a eax pop %edx # Restaurar registros. pop %ecx pop %ebx pop %ebp ret
Los asientos están numerados tal que el primero tiene el número cero, el segundo el 1, y así sucesivamente. Escribir la rutina libre que dado un número de 0 al número de asientos menos uno y la dirección de memoria donde comienza la representación del aforo (depositados en la pila en este orden) devuelve a través del registro %eax 0 si el asiento está libre y 1 si está ocupado. Los parámetros se depositan en la pila tal y como indica la siguiente figura:
Se valorará la versión que no utilice un bucle para acceder a la estructura de datos.
Solución:libre: push %ebp mov %esp, %ebp push %ebx # Salvar registros push %ecx push %edx mov 8(%ebp), %ebx # ebx = @ base de la estructura de datos mov 12(%ebp), %ecx # ecx = índice del asiento al que acceder mov 12(%ebp), %edx # edx = otra copia del índice anterior and $0x1F, %ecx # ecx contiene los últimos 5 bits del índice sar $5, %edx # edx desplazado 5 posiciones. mov (%ebx, %edx, 4), %eax # cargar 32 bits de la posicion con indice edx sar %cl, %eax # Desplazar el resultado ecx bits and $1, %eax # Quedarse con el último bit pop %edx # Restaurar registros pop %ecx pop %ebx pop %ebp ret
Apartado 1 (16 puntos)
Sobre la ruta de datos de Símplez nos planteamos si es posible implementar la instrucción LD utilizando los siguientes modos de direccionamiento:
Obsérvese que, en ambos casos, AC actúa tanto como registro para el direccionamiento como destino de la instrucción. Es decir, el contenido inicial de AC justo antes de ejecutar la instrucción correspondiente se utilizaría para calcular la dirección efectiva. Posteriormente, el dato leído de la memoria principal se guardaría en AC, con lo que se perdería el contenido inicial de AC.
Se pide: para cada uno de los modos de direccionamiento indicados, diga si es o no posible implementar la instrucción LD sobre la ruta de datos de Símplez. En caso de que no sea posible, razone la respuesta. En caso de que sea posible, indique para cada ciclo de reloj la o las expresiones en el lenguaje de transferencia entre registros que describan las operaciones a realizar en la ruta de datos de Simplez para ejecutar la instrucción.
Nota: se supone que se utiliza un secuenciador microprogramado del estilo del diseñado para Símplez original. Por lo tanto, no es necesario tener el código de operación de la instrucción que se está ejecutando en RI.
Solución:
Es posible implementar la instrucción LD con los dos modos de direccionamiento propuestos. En el caso del modo registro indirecto, el contenido de AC se puede llevar a RA a través del registro RI.
En el caso del modo Base + Desplazamiento, no es posible llevar el contenido de CD a la entrada de la UAL desde RI para calcular la suma que nos piden. No obstante, dado que la instrucción sigue estando en Memoria Principal en la dirección que hay en el bus de direcciones (el contenido de RA no ha cambiado), podemos extender la lectura un ciclo de reloj adicional. En este segundo ciclo de reloj, la instrucción se suma al contenido de AC. No es posible realizar dicha suma en el ciclo de reloj en el que se lee la instrucción, ya que hasta el flanco de bajada del reloj el secuenciador no conoce de que instrucción se trata. Una vez realizada la suma y guardada en AC, se llevan los 9 bits menos significativos a RA según lo explicado en el caso del modo registro indirecto.
Las operaciones a realizar en cada ciclo de reloj para ejecutar una instrucción LD, modo registro indirecto serían las siguientes:
Ciclo de reloj | Operaciones a realizar en la ruta de datos |
1 | (MP[RA]) -> RI; (CP) + 1 -> CP |
2 | (AC) -> RI |
3 | (CD) -> RA |
4 | (MP[RA]) -> AC |
3 | (CP) -> RA |
Las operaciones a realizar en cada ciclo de reloj para ejecutar una instrucción LD, modo Base + Desplazamiento serían las siguientes:
Ciclo de reloj | Operaciones a realizar en la ruta de datos |
1 | (MP[RA]) -> RI; (CP) + 1 -> CP |
2 | (MP[RA]) + (AC) -> AC |
3 | (AC) -> RI |
4 | (CD) -> RA |
5 | (MP[RA]) -> AC |
6 | (CP) -> RA |
Apartado 2 (16 puntos)
En este ejercicio vamos a tratar de implementar una instrucción que imite a la instrucción add %eax, etiqueta del Pentium. Esta nueva instrucción (a la que asignaremos el nemónico ADD) hace lo siguiente: "Suma el contenido del acumulador con el contenido de la palabra de memoria principal cuya dirección está indicada en el campo CD de la instrucción, dejando el resultado en dicha palabra de memoria principal" (como puede observar en esta instrucción la palabra de memoria principal es a la vez operando y resultado de la instrucción). Al terminar de ejecutarse esta instrucción el contenido del acumulador debe de ser el mismo que el que había justo antes de empezar a ejecutarse la instrucción.
En una hoja adjunta se presenta la ruta de datos de SímplezJun03, con la que se pretende implementar la nueva instrucción ADD. Esta nueva ruta de datos es igual a la original de Símplez excepto por lo siguiente:
Se pide: escriba un cronograma que permita ejecutar la nueva instrucción ADD que se ha descrito en este ejercicio.
Solución:
La solución que se propone consiste en, una vez leída la instrucción y llevado el campo CD de la misma a RA, leer la palabra de memoria a sumar, dejando el dato en AUX. A continuación, y en un único ciclo de reloj, se suma el contenido de AC y AUX y se lleva a la salida de la UAL (la entrada de AC) y se lleva el contenido de AC al bus de datos (la entrada de AUX). En el flanco de bajada de ese mismo ciclo de reloj se cargan los datos a la entrada de AC y AUX en dichos registros, con lo que se tendrá en AUX el contenido inicial de AC y en AC la suma del contenido inicial de AC y la palabra de Memoria Principal indicada por el campo CD de la instrucción. Finalmente se lleva a Memoria Principal la suma desde AC y a AC su contenido original desde AUX.
Pueden existir otras soluciones a este problema que sean correctas.
El cronograma que se propone para implementar la instrucción pedida se puede consultar aquí.