UC3M
Fundamentos de Ordenadores II - Examen Junio 03
 
Depto. de Ingeniería Telemática 
Universidad Carlos III de Madrid

 2ª Parte: Problemas

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. 


Requisitos para aprobar el examen:
  1. Nota en el examen >= 50 puntos
  2. Nota del problema 1 >= 11 puntos
  3. Nota del problema 2 >= 8 puntos

PARTE 1: NIVEL DE MÁQUINA CONVENCIONAL

PROBLEMA 1(44 puntos)

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.

  1. 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
    	  
  2. 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.

    Paramaters in Stack

    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
    	  
  3. 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:

    Paramaters in Stack 2

    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
    	  

PARTE 2: FUNCIONAMIENTO INTERNO DEL ORDENADOR

PROBLEMA 2 (32 puntos)

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í.