Fundamentos de Ordenadores II  - Examen Junio 01
Ingeniero de Telecomunicación
 
Depto. de Ingeniería Telemática 
Universidad Carlos III de Madrid

 2ª Parte: Problemas
Duración: 1 hora 45 minutos 
Puntuación 6.8 puntos (sobre 10)
Fecha: 27 de junio de 2001
Nota: Se podrán usar libros y apuntes. 

PARTE 1: NIVEL DE MÁQUINA CONVENCIONAL

1er PROBLEMA (1.4 puntos)

En el siguiente programa (realizado en ensamblador de Algorítmez):

        org 0
        ld .1, #200
        ld .2, #150
        ld .3, #100
        ld .14, #0
        st.b .1, /60000
        st.b .2, /50000
        st.b .3, /40000
        call subruti
        ld.b .1, /60000
        ld.b .2, /50000
        ld.b .3, /40000
        halt
subruti ld .1, #3000
        ld .2, #H'7070
bucle   sub .1, #1
        bz /fin
        push .2
        br bucle
fin     ld .2, #3000
bucle2  sub .2, #1
        bz /fin2
        pop .3
        br bucle2
fin2    clr .1
        clr .2
        clr .3
        ret
        end
Explicar paso a paso la ejecución del programa. ¿Cuál es el valor final de los registros utilizados (R1, R2, R3, R14)?

Solución:

El programa comienza salvando el contenido de los registros que va a emplear la subrutina. A continuación, llama a "subruti", que se dedica a introducir en la pila 3000 palabras iguales y a volverlas a extraer, tras lo cual limpia los registros que ha empleado y retorna. Tras regresar de la subrutina, el programa recupera el valor "original" de los registros y termina.

R1: 70'H (112'D)

R2: 150'D

R3: 100'D

R14: 0'D

R1 no recupera su valor original porque éste ha sido machacado por la pila.
 

2o PROBLEMA (1.8 puntos)

Necesitamos un programa que calcule el valor absoluto de la diferencia entre los sumatorios de números pares e impares de un array. Para ello, tenemos ya escrito el siguiente pseudocódigo que soluciona el problema:

pares = 0
impares = 0
for (i=0; i < N; i++) {
        if (VEC[i] & H'0001) {
                impares += VEC[i]
        } else {
                pares += VEC[i]
        }
}
if (pares > impares) {
        dif = pares - impares
} else {
        dif = impares - pares
}
Deberá escribirse una versión en ensamblador de este programa, que comience en la dirección 0 de memoria y que termine con una instrucción HALT. Al final del mismo, tendremos las siguientes pseudoinstrucciones.
N EQU 50 ; tamaño del array
ORG 1000
VEC DATA ... ; el array VEC, de tamaño N, que abarca desde VEC[0] a VEC[N-1]
AUX RES 1 ; palabra auxiliar para operaciones temporales (pueden haber más)
En ellas se define a N como una constante que indica el tamaño del array (en palabras de 16 bits) y se define VEC como un array de tamaño N que se posiciona a partir de la dirección 1000 y cuyos elementos están almacenados consecutivamente dentro del array. Podemos suponer que el array estará cargado en memoria en el momento de la ejecución. Para operaciones temporales, disponemos también de una palabra en la dirección AUX, aunque en caso necesario podemos definir más palabras temporales justo a continuación si se considera conveniente.

A la hora de escribir la versión en ensamblador del programa, deberá seguirse la siguiente correspondencia entre las variables del pseudocódigo y los registros del programa en ensamblador.

.0 = i, .1 = pares, .2 = impares, .3 = dif. El resto de los (.4 ... .13) pueden usarse para lo que se quiera.

No hace falta salvaguardar los registros. Al final de la ejecución, .3 debe contener el resultado de la variable dif, .2 debe contener impares y .1 debe contener pares.

Solución:

        ORG 0
        LD .1, #0       ; pares = 0
        LD .2, #0       ; impares = 0
        LD .0, #0       ; i = 0
BUCLE   CMP .0, #D'100  ; (i >= N)? (2 bytes)
        BNN FINBUC
        LD .4, /VEC[.0]
        AND .4, #0001   ;  (VEC[i] par?)
        BZ ELSE1
        ADD .2,/VEC[.0] ; (impares += VEC[i])
        BR FINIF1
ELSE1   ADD .1,/VEC[.0] ; (pares += VEC[i])
FINIF1  ADD .0, #2      ; i++ (2 bytes)
        BR BUCLE
FINBUC  ST .1, /AUX
        CMP .2, /AUX    ; (impares >= pares)?
        BNN ELSE2
        PUSH .1
        POP .3          ; dif = pares
        ST .2, /AUX
        SUB .3, /AUX    ; dif = pares - impares
        BR FIN
ELSE2   PUSH .2
        POP .3          ; dif = impares
        ST .1, /AUX     ; opcional, no hace falta
        SUB .3, /AUX    ; dif = impares - pares
FIN     HALT
N EQU 50
ORG 1000
VEC DATA N
AUX DATA 1
END
 

PARTE 2: FUNCIONAMIENTO INTERNO DEL ORDENADOR

3er PROBLEMA (1.8 puntos)

Se desea diseñar un secuenciador microprogramado para cierto ordenador. Las características del secuenciador a diseñar son las siguientes:

  1. El secuenciador dispone de un registro uRA que está conectado a la entrada de direcciones de la Memoria de Control (MC) del secuenciador. Por lo tanto, la palabra de MC que está siendo leída en un cierto instante es aquella cuya dirección está almacenada en uRA. (igual que en Símplez)
  2. El retardo de MC es despreciable respecto al ciclo de reloj. (igual que en Símplez)
  3. Las microórdenes generadas por el secuenciador cambian en el flanco de bajada del reloj. (igual que en Símplez)
  4. El ordenador dispone de un Registro de Instrucción (RI) en el que se guarda la instrucción que está siendo ejecutada. Cuando se lee una instrucción de memoria (todas las instrucciones se pueden leer realizando una única lectura de la Memoria Principal), simultáneamente se escribe el código de operación de la instrucción que está siendo leída en el registro uRA.  (igual que en Símplez)
  5. El repertorio de instrucciones del ordenador consta de 8 instrucciones. Entre ellas, existe una instrucción HALT, que para la ejecución del ordenador. El código de operación de dicha instrucción es el 7. (igual que en Símplez)
  6. La microinstrucción en la que se lee una nueva instrucción de la Memoria Principal es la de dirección 15. (igual que en Símplez)
  7. A cada microorden se le asigna un bit de las microinstrucciones. (igual que en Símplez)
  8. Para implementar el secuenciador se necesitan 64 microinstrucciones.
  9. Para controlar la ruta de datos se utilizan 20 microórdenes.
  10. Se dispone de dos indicadores: biestable Z (indica si la última operación en la UAL ha dado como resultado 0) y biestable V (indica si en la última operación en la UAL se ha producido desbordamiento).
  11. La dirección de la siguiente microinstrucción a la de dirección 25 es la 30 si Z=0 y la 31 si Z=1.
  12. La dirección de la siguiente microinstrucción a la de dirección 35 es la 40 si V=1 y la 41 si V=0.
Diseñe todos los circuitos digitales necesarios para implementar este secuenciador. Si lo necesita, puede definir microórdenes internas al secuenciador, indicando su función y la dirección de las microinstrucciones en las que se activan dichas microórdenes. Indique el tamaño de las palabras de MC, indicando el número de bits dedicados a definir las microórdenes a activar y el número de bits dedicados a definir la dirección de la siguiente microinstrucción. Indique el contenido de los bits dedicados a definir la dirección de la siguiente microinstrucción (en decimal) para las microinstrucciones de dirección 25 y 35.

Nota: para el diseño del secuenciador puede utilizar exclusivamente los siguientes componentes:

Solución:

Dado que las características del secuenciador a diseñar definidas en los puntos 1 al 7 del enunciado  coinciden con las del secuenciador microprogramado de Símplez, parece razonable partir de dicho secuenciador, y estudiar que modificaciones son necesarias para cumplir con los puntos 8 al 12.

El punto 8 me dice que la Memoria de Control (MC) ha de tener 64 palabras. Como sabemos, las microinstrucciones tienen un campo (DS) en el que se indica la dirección de la siguiente microinstrucción a leer. Como quiera que las primeras 8 microinstrucciones serán las leídas al comienzo de la ejecución de las instrucciones, según lo dicho en los puntos 4 y 5, el campo DS ha de poder direccionar las palabras de la dirección 8 a la 63 de MC (56 palabras) . Por lo tanto, para especificar la dirección de la siguiente microinstrucción necesitamos 6 bits (con 5 bits sólo se podrían direccionar 32 palabras).

Con 6 bits podemos identificar directamente la dirección de la siguiente microinstrucción (en vez de solamente los bits menos significativos, como se hacía en Símplez). Por lo tanto, vamos a simplificar el cálculo de DMC. Si sco=0, DMC lo tomaremos directamente de DS (salvo lo explicado más adelante para los puntos 10, 11 y 12) y si sco=1, DMC será el código de operación de la nueva instrucción a ejecutar.

Para implementar el cálculo de DMC (figura 3), basta un multiplexor con 2 entradas de 6 bits cada una, controlado por la microorden sco. Los 3 bits menos significativos de la entrada 1 se tomarán de los bits del bus de datos por los que circula el código de operación de las instrucciones y se completan los 3 bits más significativos con ceros. La entrada 0 se tomará directamente de DS (salvo lo explicado más adelante para los puntos 10, 11 y 12).

El punto 10 simplemente nos informa de la existencia de dos indicadores. Los puntos 11 y 12 me indican que esos indicadores influyen en la dirección de la siguiente microinstrucción de dos microinstrucciones. Vamos a aprovechar que las posibles direcciones siguientes en los dos casos sólo se diferencian en el bit menos significativo. Vamos a definir el valor del campo DS para esas dos microinstrucciones como un 0 para el bit menos significativo y los bits más significativos serán los correspondientes a la dirección de la siguiente microinstrucción, que, como se ha dicho, son independientes del valor del indicador. Un bloque de circuitería se encargará de poner a 1 el bit menos significativo de DS cuando sea necesario. Por lo tanto, el campo DS vale 30 para la microinstrucción de dirección 25 y 40 para la de dirección 35.
 
 


figura 1: diseño del secuenciador microprogramado

Vamos a definir un bloque de circuitería (figura 2) que colocaremos entre la salida DS de MC y la entrada 0 del multiplexor indicado anteriormente. La salida de ese bloque la llamaremos DSE (DS efectiva). Este bloque no modifica los bits 1 al 5 de DS. Para el bit 0 de DSE lo tomaremos de una puerta OR con tres entradas. Una de ellas es DS0. Las otras 2 vienen de dos puertas AND. Una de ellas se encarga de poner el bit menos significativo de DSE a 1 cuando se está leyendo la microinstrucción de dirección 25 y (Z)=1. La otra se encarga de poner el bit menos significativo de DSE a 1 cuando se está leyendo la microinstrucción de dirección 35 y (V)=0.Tienen dos entradas; una de ellas es una microorden interna al secuenciador. La microorden bbz solamente vale 1 para la palabra de MC de dirección 25. La microorden bbv solamente vale 1 para la palabra de MC de dirección 35. De esta forma, se garantiza que para todas las demás palabras de MC la salida de las puertas AND es 0, por lo que el bit menos significativo de DSE coincide con el bit menos significativo de DS.

Finalmente, el punto 9 nos dice que la ruta de datos se controla por medio de 20 microinstrucciones. Por lo tanto, las palabras de MC son de 30 bits: 24  corresponden a las microinstrucciones (20 de la ruta de datos más 4 internas al secuenciador: sco, cbf, bbz, bbv) y 6 de campo DS. El diseño completo se presenta en la figura 1.
 
 


figura 2: detalle del bloque (1) de la figura 1

Terminado el diseño, podemos contestar a todas las preguntas que se plantean en el enunciado:



figura 3: detalle del bloque (2) de la figura 1




4º PROBLEMA (1.8 puntos)

La figura 1 muestra la ruta de datos de Símplez*. Los cambios introducidos respecto a Símplez son los siguientes:

  1. La salida de la unidad aritmético-lógica está conectada a un registro (además de AC), llamado AUX. Al igual que AC, AUX es un registro de 12 bits. El registro AUX es un registro auxiliar. Su función es almacenar resultados intermedios durante la ejecución de una instrucción.  Por lo tanto, al implementar una instrucción, podemos modificar libremente su contenido, sin tener que preocuparnos de conservar su contenido inicial.
  2. El registro AUX dispone de una entrada de habilitación (microorden eau). El contenido del registro AUX sólo se actualiza cuando la microorden eau está activa.
  3. La entrada 1 de la UAL siempre se toma de AC.
  4. Es posible escribir en el bus D tanto el contenido de AC como el de AUX. Para ello, un multiplexor (MUX) que toma sus entradas de AC y AUX está conectado con el bus D a través de la puerta triestado controlada con la microorden sac. La microorden rs controla el multiplexor. Si rs está activa, a la salida del multiplexor está el dato guardado en AUX y en caso contrario el dato guardado en AC.

figura 1: ruta de datos de Símplez*

Conteste a las siguientes preguntas:

  1. Escriba un microprograma para Símplez que implemente una instrucción que multiplique por 4 el contenido de AC, dejando el resultado en AC. Suponga que no se produce desbordamiento. (0.4 puntos)
  2. Escriba un microprograma para Símplez* que implemente una instrucción que multiplique por 14 el contenido de AC, dejando el resultado en AC y utilizando un máximo de 6 microinstrucciones. Suponga que no se produce desbordamiento. (0.7 puntos)
  3. Ahora se desea implementar la misma instrucción que en la pregunta 2, pero de forma que el contenido del registro AUX al final de la instrucción sea el mismo que el contenido del registro AUX antes de comenzar a ejecutarla. Para ello, en el campo CD de la instrucción se especifica la dirección de una palabra de memoria donde deberá guardar el contenido inicial del registro AUX, para poder recuperarlo al final de la instrucción. Escriba un microprograma para Símplez* que implemente esta instrucción utilizando el mínimo número de microinstrucciones que sea posible. (0.7 puntos)
Solución:

Las ideas básicas que hay que considerar para resolver este problema son las siguientes:

  1. Pregunta 1: activando la microorden sac, se pasa el contenido de AC al bus de datos, y de ahí a la entrada 2 de la UAL. Si, simultáneamente activamos la microorden sum de la UAL, a la salida de la UAL aparecerá (AC) + (AC) = 2 * (AC). Finalmente, con eac se guarda el resultado en el acumulador. Repitiendo el proceso 2 veces se consigue multiplicar por 4 el contenido del acumulador.
  2. Pregunta 2: utilizando la misma técnica que en el apartado 1 es posible calcular 2n * (AC). El registro AUX se puede utilizar para almacenar sumas de los valores que se van obteniendo en el registro AC. Utilizando esta técnica es posible multiplicar (AC) por cualquier número entero positivo. No hay más que descomponer dicho número en sumas de potencias de 2. En nuestro caso 14 * (AC) = 2 * (AC) + 4 * (AC) + 8 * (AC). Nota: Hay otras posibles soluciones utilizando AC y AUX.
  3. Pregunta 3: esta sencilla pregunta se puede resolver simplemente aplicando lo explicado en clase respecto a la lectura y escritura en la Memoria Principal de Símplez.
A continuación se presentan los microprogramas pedidos. Para calcular al dirección siguiente se ha supuesto el mismo mecanismo que en el caso del secuenciador microprogramado de Simplez. Otros mecanismos pueden ser aceptados como válidos.

PREGUNTA 1
 

DMC CuO DS
x1 sac, sum, eac ds1
ds1 + 8 sac, sum, eac, scp, era dfinal
dfinal + 8 lec, eri, incp, sco  

PREGUNTA 2
 

DMC CuO DS
x2 sac, sum, eac, eau ds2
ds2 + 8 sac, sum, eac ds2 + 1
ds2 + 1 + 8 rs, sac, sum, eau ds2 + 2
ds2 + 2 + 8 sac, sum, eac ds2 + 3
ds2 + 3 + 8 rs, sac, sum, eac, scp, era dfinal
dfinal + 8 lec, eri, incp, sco  

 
 
 
 

PREGUNTA 3
 

DMC CuO DS
x3 sri, era ds3
ds3 + 8 rs, sac, esc ds3 + 1
ds3 + 1 + 8 rs, sac ds3 + 2
ds3 + 2 + 8 sac, sum, eac, eau ds3 + 3
ds3 + 3 + 8 sac, sum, eac ds3 + 4
ds3 + 4 + 8 rs, sac, sum, eau ds3 + 5 
ds3 + 5 + 8 sac, sum, eac ds3 + 6
ds3 + 6 + 8 rs, sac, sum, eac ds3 + 7
ds3 + 7 + 8 lec, tra2, eau ds3 + 8
ds3 + 8 + 8 scp, era dfinal
dfinal + 8 lec, eri, incp, sco