UC3M

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

 2ª Parte: Problemas

Duración: 3 horas 30 minutos 
Puntuación 7.6 puntos (sobre 10)
Fecha: 26 de junio de 2002
Nota: Se podrán usar libros y apuntes. 


Requisitos para aprobar la asignatura:
  1. Nota en el examen >= 5.0 puntos
  2. Suma de las notas de los problemas 1 y 2 >= 1.1 puntos
  3. Suma de las notas de los problemas 3 y 4 >= 0.8 puntos

PARTE 1: NIVEL DE MÁQUINA CONVENCIONAL

1er PROBLEMA (1.7 puntos)
 
  Dado el siguiente código:

.data

fila1:
      .byte 0, 0, 1, 1
fila2:
      .byte 1, 0, 0, 0
fila3:
      .byte 0, 0, 1, 1
fila4:
      .byte 0, 1, 1, 1
fila5:
      .byte 0, 0, 0, 0
x:
      .int 0
y:
      .int 0
mensaje1:
      .string "(%d,%d)\n"
mensaje2:
      .string "Obstáculo al este\n"
mensaje3:

      .string "Obstáculo al sur\n"

      .text

      .global main

main:
      pushl %ebp
     
movl %esp,%ebp
      pushl %eax
      pushl %ebx
      pushl %ecx
bucle:
      pushl y
      pushl x
      pushl $mensaje1

 

              
      call printf
      addl $12, %esp
      cmpl $3, x            
      jz fin
      movl x, %eax
      incl %eax             
      movl y, %ebx
      addl $fila1, %eax
      movb (%eax, %ebx, 4), %cl
      cmpb $1, %cl
      jz obstaculoEste
      incl x
     
jmp bucle

obstaculoEste:
      pushl %eax
      pushl $mensaje2
      call printf
      addl $4, %esp
      popl %eax
     
decl %eax

     
incl %ebx

     
movb (%eax, %ebx, 4), %cl

     
cmpb $1, %cl

     
jz obstaculoSur

     
movl %ebx, y

     
jmp bucle

obstaculoSur:
      pushl $mensaje3
      call printf
      addl $4, %esp
     
fin:
      popl %ecx
      popl %ebx
      popl %eax    

      movl %ebp,%esp
      popl %ebp
      ret

a) Escribir la secuencia de mensajes que aparecen en pantalla durante la ejecución del programa. (1.3 puntos)
Solución:

(0,0)
(1,0)
Obstáculo al este
(1,1)
(2,1) 
(3,1)

b) Suponiendo que este programa implemente un algoritmo para salir del laberinto descrito por las etiquetas fila1, fila2, fila3, fila 4 y fila 5 (donde los unos indican las casillas que son pared), ¿qué cero cambiarías por un uno para que siguiese habiendo un camino hasta la salida, pero de forma que el algoritmo no fuese capaz de encontrarlo? (La entrada al laberinto es la casilla (0,0), y llegar a la salida significa alcanzar una posición libre en la cuarta columna). Escribir la secuencia de mensajes que escribiría el programa en ese caso. (0.4 puntos)
Solución:

Dos casos posibles:

(0,0)
(1,0)
Obstáculo al este
(1,1) 
(2,1) 
Obstáculo al este 
Obstáculo al sur

2o PROBLEMA (2.7 puntos)

Se dispone de un programa que manipula el nombre y los apellidos de un conjunto de usuarios. Para ello se manipulan dos tablas que comienzan en las posiciones de memoria con etiquetas nombres y apellidos y que contienen las direcciones donde comienzan el nombre y los apellidos del usuario respectivamente. El tamaño de estas tablas es idéntico y está almacenado en un número de 32 bits en una posición de memoria con etiqueta tamaño. Este tamaño es distinto de cero.

Se pide escribir los siguientes fragmentos de código documentando detalladamente la solución propuesta:

  1. Rutina cuenta que recibe dos parámetros por la pila. El primero que se deposita es la dirección de comienzo de una de las tablas, y el segundo un índice, de 32 bits. El primer elemento de las tablas se encuentra en la posición con índice 0, el segundo en la posición con índice 1, etc. La rutina devuelve el número de caracteres del string apuntado en la posición de la tabla indicada por el índice. El resultado se debe devolver en el registro %eax. (0.9 puntos)

    Solución

    cuenta: push %ebp
            mov %esp, %ebp
    
            push %ebx
            push %ecx
    
            mov $0, %eax
            mov 8(%ebp), %ebx
            mov 12(%ebp), %ecx
            mov (%ecx, %ebx, 4), %ebx
    
    cond:   cmpb $0, (%ebx, %eax)
            jz done
            inc %eax
            jmp cond  
          
    done:   pop %ecx
            pop %ebx
    
            mov %ebp, %esp
            pop %ebp
            ret
              
  2. Rutina suma que no recibe parámetros y calcula la suma del tamaño de todos los strings de las dos tablas y devuelve el resultado a través de la pila. Se debe utilizar la rutina del apartado anterior. Recuerde que es la rutina que llama la que hace el hueco en la pila donde la rutina llamada deja los resultados. (0.9 puntos)

    Solución

    suma:   push %ebp
            mov %esp, %ebp
    
            push %eax
            push %ebx
            push %ecx
           
            mov $0, %ebx
            mov tamaño, %ecx
    cond:   dec %ecx
            jn done
    
            push $nombre,
            push %ecx
            call cuenta
            add %eax, %ebx
            mov $apellidos, 4(%esp)
            call cuenta
            add %eax, %ebx
            add $8, %esp
            jmp cond
    
    done:   mov %ebx, 8(%ebp)
    
            pop %ecx
            pop %ebx
            pop %eax
           
            mov %ebp, %esp     
            pop %ebp
            ret
              
  3. Rutina swap que recibe como parámetros a través de la pila dos índices y que intercambia la posición de los datos de dos usuarios en las tablas. No devuelve resultado. Por ejemplo, si en la posicion i están los datos "nombre1" y "apellidos1", y en la posición j los datos "nombre2" y "apellidos2" en sus respectivas tablas, tras ejecutar esta rutina con parámetros (i, j) los datos se han intercambiado de posición ("nombre1"y "apellidos1" en posición j y "nombre2" y "apellidos2" en posición i). (0.9 puntos)

    Solución

    La observación clave a realizar es que cambiar los strings de posición tan solo requiere intercambiar las direcciones en las tablas. No es necesario mover los strings de un lugar a otro de memoria.

    swap:   push %ebp                       /* Guardar y asignar ebp */
            mov %esp, %ebp
    
            push %eax
            push %ebx
            push %ecx
            push %edx
           
            mov 8(%ebp), %eax               /* Almacena el indice i en eax */
            mov 12(%ebp), %ebx              /* Almacena el indice j en ebx */
    
            mov nombre(, %eax, 4), %ecx     /* Mover el primer nombre a ecx */
            mov nombre(, %ebx, 4), %edx     /* Mover el segundo nombre a edx */
          
            mov %ecx, nombre(, %ebx, 4)     /* Mover %ecx a la posicion j */
            mov %edx, nombre(, %eax, 4)     /* Mover %edx a la posicion i */
    
            mov apellidos(, %eax, 4), %ecx  /* Mover el primer apellido a ecx */
            mov apellidos(, %ebx, 4), %edx  /* Mover el segundo apellido a edx */
    
            mov %ecx, apellidos(, %ebx, 4)  /* Mover %ecx a la posicion j */
            mov %edx, apellidos(, %eax, 4)  /* Mover %edx a la posicion i */
    
            pop %edx
            pop %ecx
            pop %ebx
            pop %eax
           
            mov %ebp, %esp
            pop %ebp                        /* Restaurar EBP */
            ret	
              

PARTE 2: FUNCIONAMIENTO INTERNO DEL ORDENADOR

3er PROBLEMA (1.2 puntos)

Se desea modificar el comportamiento de la instrucción ADD de Símplez. El comportamiento que se desea que tenga esta nueva versión es el siguiente. Suma dos palabras de MP, dejando el resultado en el acumulador. Para  poder indicar las direcciones de las dos palabras de MP que se desea sumar, la instrucción ADD se codifica ahora por medio de dos palabras consecutivas de MP. La primera tiene en los tres bits más significativos el código de operación (010) y en los 9 bits restantes la dirección de la primera palabra de MP que se desea sumar. Los tres bits más significativos de la segunda palabra de la instrucción valen 000. Los 9 bits menos significativos de la segunda palabra de la instrucción contienen la dirección de la segunda palabra de MP a sumar. La ruta de datos no cambia.    

Se pide:

  1. Escriba un microprograma que implemente esta nueva versión de la instrucción ADD.  (0.6 puntos)
  2. Se desea diseñar un secuenciador cableado para esta nueva versión de Símplez. Se realiza un diseño con biestables que permite conocer el estado de ejecución. Dicho estado de ejecución indica exclusivamente el número de orden del ciclo de reloj de la instrucción (primer ciclo de reloj de la instrucción, segundo ciclo de reloj, etc.), independientemente de la instrucción que se está ejecutando. El secuenciador no contiene ningún elemento de memoria adicional. ¿Sería posible en estas condiciones realizar dicho secuenciador cableado? Razone la respuesta. (0.6 puntos)

Solución:

APARTADO 1

El microprograma a realizar esencialmente consiste en el microprograma de la instrucción LD seguido del microprograma de la instrucción ADD.

Dir. MC Microórdenes DS
x sri, era d
d+8 lec, tra2, eac d+1
d+9 scp, era d+2
d+10 lec, eri, incp d+3
d+11 sri, era

d+4

d+12 lec, sum, eac d+5
d+13 scp, era dfinal
dfinal+8 lec, eri, incp, sco  

APARTADO 2

Si sería posible realizar el secuenciador cableado en las condiciones indicadas. Recuérdese que los circuitos combinacionales que generan las microórdenes toman como entradas el código de operación de la instrucción, el estado de ejecución y el biestable Z. Estas informaciones estarían disponibles, salvo en el caso de la nueva instrucción ADD, en la cuál a partir del sexto ciclo de reloj (inmediatamente después del ciclo de reloj en el que se lee la microinstrucción de dirección d+10) el código de operación desaparece, ya que la nueva lectura de MP escribe 000 en CO. Pero como no hay ninguna otra instrucción con más de 4 ciclos de reloj, una vez superado el quinto ciclo sabemos que se trata de la instrucción ADD aunque haya 000 en CO.


4º PROBLEMA (2 puntos)

Se desea diseñar una versión de Símplez, que llamaremos Símplez-SIMD, en la que se modifica el repertorio de instrucciones de Símplez, añadiendo tres instrucciones SIMD (Single Instruction Multiple Data). Las instrucciones SIMD se caracterizan porque la ejecución de una única instrucción se realiza sobre varios datos. En nuestro caso, se sustituye el registro AC de Símplez por 16 registros de próposito general de 16 bits (identificados por R[0] a R[15]), encapsulados en una Memoria Local, que llamaremos ML. Las nuevas instrucciones STS, LDS y ADDS, que sustituyen a ST, LD y ADD realizan operaciones sobre 1 a 16 datos de 16 bits. La nueva Memoria Principal, MP, tiene una capacidad de 65536 palabras de 16 bits, es decir, utiliza direcciones y datos de 16 bits. Por lo tanto, tanto el bus de direcciones como el bus de datos son de 16 bits.

Concretamente la funcionalidad y la sintaxis en ensamblador de las instrucciones STS, LDS y ADDS es la siguiente:

- Instrucción STS(m) .n, /p. Copia el contenido del registro R[n] en la palabra de MP de dirección p; copia el contenido del registro R[n+1] en la palabra de MP de dirección p+1; ...;copia el contenido del registro R[n+m-1] en la palabra de MP de dirección p+m-1. Por ejemplo la instrucción:
 

STS(4) .3, /67
copia el contenido del registro R[3] en la palabra de MP de dirección 67; copia el contenido del registro R[4 ]en la palabra de MP de dirección 68; copia el contenido del registro R[5] en la palabra de MP de dirección 69 y copia el contenido del registro R[6] en la palabra de MP de dirección 70.

- Instrucción LDS(m) .n, /p. Copia el contenido de la palabra de MP de dirección p en el registro R[n]; copia el contenido de la palabra de MP de dirección p+1 en el registro R[n+1]; ...; copia el contenido de la palabra de MP de dirección p+m-1 en el registro R[n+m-1]. Por ejemplo la instrucción:
 

LDS(4) .3, /67
copia el contenido de la palabra de MP de dirección 67 en el registro R[3]; copia el contenido de la palabra de MP de dirección 68 en el registro R[4]; copia el contenido de la palabra de MP de dirección 69 en el registro R[5] y copia el contenido de la palabra de MP de dirección 70 en el registro R[6].

- Instrucción ADDS(m) .n, /p. Suma el contenido de la palabra de MP de dirección p con el contenido del registro R[n], dejando el resultado en R[n]; suma el contenido de la palabra de MP de dirección p+1 con el contenido del registro R[n+1], dejando el resultado en R[n+1]; ...;suma el contenido de la palabra de MP de dirección p+m-1 con el contenido del registro R[n+m-1], dejando el resultado en R[n+m-1]. Por ejemplo la instrucción:

ADDS(4) .3, /67
suma el contenido de la palabra de MP de dirección 67 con el contenido del registro R[3], dejando el resultado en R[3]; suma el contenido de la palabra de MP de dirección 68 con el contenido del registro R[4], dejando el resultado en R[4]; suma el contenido de la palabra de MP de dirección 69 con el contenido del registro R[5], dejando el resultado en R[5] y suma el contenido de la palabra de MP de dirección 70 con el contenido del registro R[6], dejando el resultado en R[6].

El formato de instrucciones es el siguiente. Las instrucciones pueden ocupar una o dos palabras (16 o 32 bits). Las instrucciones CLR, DEC y HALT, cuya funcionalidad es la misma que en Símplez (en el caso de CLR y DEC, ahora hace falta especificar el registro de ML sobre el que operan), ocupan una sóla palabra. Las demás instrucciones ocupan dos palabras. Los campos del formato de instrucciones vienen presentados en la figura 1.
 

Formato

Figura 1: Formato de instrucciones de Símplez-SIMD

La primera palabra de la instrucción (obligatoria para todas las instrucciones) contiene 3 campos. El campo CO (obligatorio para todas las instrucciones) es de 3 bits, ocupando los bits 15 al 13 de la palabra (al igual que en Símplez, se utiliza el convenio extremista menor). El campo CR es de 4 bits, ocupando los bits 12 al 9 de la palabra. Está presente en las instrucciones que utilizan ML (STS, LDS, ADDS, CLR, DEC). Hace referencia a uno de los registros de propósito general de ML. Por ejemplo, si queremos hacer referencia al registro R[0] el campo CR debe valer 0. Finalmente, el campo NR es también de 4 bits, ocupando los bits 8 al 5 de la palabra. Se utiliza solamente en las instrucciones SIMD (STS, LDS y ADDS). Indica el número de copias o sumas a realizar menos 1. Por ejemplo, en la instrucción STS(4) .3, /67, el campo NR valdría 0011 (3 en binario).

En las instrucciones SIMD, la suma del contenido del campo CR y el contenido del campo NR deberá valer menos de 16. En caso contrario la instrucción SIMD no hará nada.

La segunda palabra se utiliza en todas las instrucciones menos CLR, DEC y HALT. Contiene la dirección de una palabra de Memoria Principal (campo CD de la instrucción). Se utiliza direccionamiento directo.


Se define asimismo un lenguaje ensamblador para Símplez-SIMD. Cada instrucción de Símplez-SIMD se escribe en una línea. En cada línea, se indica el nemónico de la instrucción y a continuación las demás informaciones que fuesen necesarias. Para hacer referencia a un registro de propósito general se utiliza un punto seguido de un número decimal (por ejemplo, .3 identifica el registro R[3]). Para hacer referencia a una dirección de Memoria Principal se utiliza el símbolo "/" seguido de un número decimal (por ejemplo /23 identifica la palabra de MP de dirección 23). Se distinguen 4 casos:
  • Instrucciones SIMD: ya se ha visto la sintaxis.
  • Instrucciones que sólo hacen referencia a MP (BR y BZ). Por ejemplo: BR /134
  • Instrucciones que sólo hacer referencia a un registro de ML (CLR y DEC). Por ejemplo: CLR .5
  • Instrucción HALT, que se escribe sin añadir nada al nemónico.
Se pide:

Apartado 1 (0.5 puntos)

Sobre Símplez-SIMD se escribe el siguiente programa que permite sumar dos listas de 6 números almacenados en MP (cada número ocupa una palabra). La primera lista ocupa las palabras de direcciones 400 a 405. La segunda lista ocupa las palabras de direcciones 408 a 413. El resultado se deja en las palabras de direcciones 416 a 421. El programa empieza en la dirección 0 de MP.

LDS(6) .0, /400
ADDS(6) .0, /408
STS(6) .0, /416
HALT

Calcule el número de accesos a MP (lecturas y escrituras) necesarios para ejecutar este programa. Escriba en ensamblador de Símplez un programa que haga lo mismo que éste, es decir, un programa que sume dos listas de números almacenadas en MP en las palabras de direcciones 400 a 405 y 408 a 413 y deje el resultado en las palabras de MP de direcciones 416 a 421. Calcule el número de accesos a MP necesarios para ejecutar el programa en Símplez que ha escrito.

Solución:

Accesos a MP para programa Símplez-SIMD= 25 (18 para leer y escribir los datos; 7 para leer las instrucciones).

Programa equivalente en Símplez:

LD /400
ADD /408
ST /416
LD /401
ADD /409
ST /417
LD /402
ADD /410
ST /418
LD /403
ADD /411
ST /419
LD /404
ADD /412
ST /420
LD /405
ADD /413
ST /421
HALT

Accesos a MP para programa Símplez= 37 (18 para leer y escribir los datos; 19 para leer las instrucciones)

Apartado 2 (0.5 puntos)

Suponga que en Símplez se dispusiese de los modos de direccionamiento indexado y directo. Se supone de la existencia de un registro de índice además del acumulador. Se supone que todas las instrucciones ocupan una palabra de MP independientemente del modo de direccionamiento. ¿Sería posible escribir un programa equivalente al realizado en el apartado 1 para Símplez pero que necesitase un número menor de accesos a MP para ser ejecutado? Razone la respuesta.

Solución:

No sería posible escribir un programa que requiriese un número menor de accesos a MP. El direccionamiento indexado me permitiría sustituir el código anterior por un bucle, pero las instrucciones LD, ST y ADD a ejecutar serían las mismas, por lo que el número de accesos a MP sería el mismo o mayor.


Apartado 3 (1  punto)

En una hoja aparte se presenta la ruta de datos (incompleta) de Símplez-SIMD.

Comparada con Símplez, se ha sustituido el registro acumulador (AC) de Símplez por la Memoria Local (ML). El funcionamiento de ML es el siguiente:
  • La entrada dirml, de 4 bits, selecciona uno de los 16 registros de ML.
  • En todo momento, en la salida sal está el contenido del registro indicado por dirml.
  • Cuando eml está activa, en el flanco de bajada del reloj se guarda el dato disponible en en (de 16 bits) en el registro indicado por dirml
El resto de la ruta de datos presentada es idénica a Símplez salvo por el hecho de que los buses de datos y direcciones y los registros son todos de 16 bits. La Memoria Principal, como ya se ha explicado utiliza direcciones y datos de 16 bits. La UAL es también de 16 bits.

Complete la ruta de datos presentada de forma que sea posible implementar el repertorio de instrucciones de Símplez-SIMD. Debe de indicar:
  • Componentes que utiliza
  • Entradas de control de cada componente y su función
  • Entradas y salidas de cada componente
Razone la respuesta.  Si lo desea, puede dibujar los componentes que faltan sobre la figura 2. Puede añadir figuras adicionales.

Notas:
  1. La temporización de la MP es idéntica a la de Símplez.
  2. Si lo desea, puede añadir entradas de control a alguno de los componentes ya incluidos, indicando su funcionalidad.
  3. En los registros que utilice, si lo desea, puede utilizar entradas de control para incrementar y decrementar el registro. Si tiene las dos funciones, obviamente, deberán existir dos entradas de control diferentes. 
  4. Exclusivamente podrá utilizar los siguientes componentes:
  • puertas lógicas
  • puertas triestado
  • biestables
  • decodificadores
  • multiplexores
  • unidades aritmético-lógicas
  • registros
  • buses
  • memorias

Solución: (hay otras soluciones posibles)

La ruta de datos propuesta se presenta aquí. Los elementos añadidos se presentan de color rojo.

En primer lugar, debemos almacenar en la ruta de datos los campos de la instrucción que se va a ejecutar. Una posibilidad sería utilizar un registro de 16 bits para la primera palabra y otro, también de 16 bits para la segunda. El problema de este enfoque es que necesitamos poder decrementar los bits del campo NR e incrementar los bits del campo CR (cada vez que se realiza una copia o una suma en las instrucciones SIMD). Por resolver este problema utilizaremos 4 registros, todos ellos sensibles al flanco de bajada del reloj:

Para completar el diseño, debemos pensar en las operaciones que se realizarán en la ruta de datos para ejecutar cada instrucción. Para las instrucciones no SIMD el proceso es el mismo que en Símplez, salvo que, cuando sea necesario utilizar un registro de ML se utilizará el valor del registro CR para seleccionarlo.

En el caso de las instrucciones SIMD se plantea su ejecución siguiendo los siguientes pasos:

  1. Si (N) + (CR) > 15 la instrucción termina sin hacer nada.
  2. Se lleva el contenido de CD a RA.
  3. Se realiza una copia o suma. La dirección de MP está en RA. La dirección de ML está en CR. Hay que poder llevar la salida de ML (sal) al bus de datos, controlada por una puerta triestado, para el caso de STS. En el caso de ADDS o LDS, el dato a guardar en ML se toma de la UAL y el dato leído de MP es transfiere a la entrada 2 de la UAL (esto ya venía en el enunciado). En el caso de ADDS, la salida de ML debe de estar conectada a la entrada 1 de la UAL para poder efectuar la suma.
  4. Si (N)=0 hemos terminado. En caso contrario se decrementa N, se incrementa CR, se incrementa RA y se vuelve al punto 3.

Para poder realizar estas operaciones es necesario añadir lo siguiente a la ruta de datos:

Las figuras a continuación muestran los circuitos de los bloques "N=0" y "N + CR > 15".

 

Bloque "N=0"
Bloque "N + CR> 15"