EC/FC - Práctica 7: Carga y almacenamiento. Operaciones aritméticas

02 de April de 2008

Contents

Introducción

Objetivos

Al finalizar esta práctica el estudiante será capaz de:

  • Traer y llevar de memoria bytes y palabras.
  • Realizar operaciones aritméticas.
  • Realizar operaciones lógicas
  • Realizar operaciones de desplazamiento

Material necesario

Para la realización de esta práctica se necesita un ordenador personal con Windows o Linux y el simulador SPIM, disponible en http://pages.cs.wisc.edu/~larus/spim.html. Es muy recomendable que e instales este programa en tu ordenador

Evaluación de la práctica

La evaluación de la práctica comenzará antes de asistir al laboratorio. Así, el estudiante deberá reunirse con su compañero de grupo para preparar cada sesión. El trabajo previo a la prá ctica consistirá en un conjunto de actividades que nos prepararán para obtener el máximo provecho de la sesión de laboratorio. El trabajo previo tendrá una valoración variable y se mostrará al profesor de laboratorio en la primera media hora de cada sesión.

El resto de la evaluación de la práctica estará relacionado con el trabajo en la sesión presencial en el laboratorio. Cada apartado, formado por actividades diversas, tendrá una puntuación. Esta puntuación aparecerá indicada junto a cada actividad.

Trabajo previo antes del Laboratorio (3 puntos)

Para poder sacar el máximo partido a la sesión de laboratorio debes realizar las siguientes actividades:

Introduce el siguiente programa en memoria. Analiza que hace cada instrucción de almacenamiento y da la tradución y una breve descripción de cada una

  introsim.s
1   .data # zona de datos
2 palabra1: .word 0x10  
3 palabra2: .word 0x20  
4      
5   .text # zona de instrucciones
6 main: la $s0, palabra1  
7   la $s1, palabra2  
8   la $s2, 0x10010004  
9   lui $s3,0x8690  
10   ori $s3,$s3,0x1234  
11   ll $s4,0x12345678  

Trabajo en el Laboratorio (7 puntos)

Hasta ahora se ha visto cómo se puede indicar en lenguaje ensamblador que se quieren inicializar determinadas posiciones de memoria con determinados valores, cómo se pueden cargar estos valores de la memoria a los registros del procesador y cómo almacenar en memoria la información contenida en los registros. Es decir, ya se sabe cómo definir e inicializar las variables de un programa, cómo transferir el contenido de dichas variables en memoria a los registros, para así poder realizar las operaciones oportunas y, finalmente, cómo transferir el contenido de los registros a memoria para almacenar el resultado de las operaciones realizadas. Sin embargo, no se han visto cuáles son las operaciones que puede realizar el procesador. En ésta y la siguiente práctica se verán algunas de las operaciones básicas más usuales que puede realizar el procesador. Y las instrucciones que las implementan.

Operaciones aritméticas

Para introducir las operaciones aritméticas que el MIPS32 puede realizar se comienza viendo el siguiente programa que suma un operando almacenado originalmente en memoria y un valor constante proporcionado en la propia instrucción de suma. Observa que para realizar la suma, será necesario en primer lugar, cargar el valor que se quiere sumar de la posición de memoria en la que se encuentra, a un registro.

  operaddiu.s
1   .data # zona de datos
2 numero: .word 2147483647 # Max. Positivo representable en Ca2
3     # en hexadecimal 0x7fffffff
4      
5   .text # zona de instrucciones
6 main: lw $t0, numero($0)  
7   addiu $t1, $t0, 1 # $t1<-$t0+1

La instrucción addiu $t1 , $t0 , 1, que es del tipo addiu rt , rs ,Inm, realiza una suma de dos operandos sin signo. Uno de los operandos está almacenado en un registro, en rs, y el otro en la propia instrucción, en el campo Inm; el resultado se almacenará en el registro rt. Puesto que el campo destinado al almacenamiento del número inmediato es de 16 bits y el operando ha de tener 32 bits, es necesario extender la información proporcionada en Inm de 16 a 32 bits. Esta extensión se realiza en las operaciones aritméticas extendiendo el signo a los 16 bits más significativos. Por ejemplo, el dato inmediato de 16 bits 0xfffe cuando se utiliza como operando de una operaci ón aritmética, se extiende al valor de 32 bits 0xffff fffe (que en binario es 11111111 11111111 11111111 11111110).

Actividades (1 punto)

Carga el fichero anterior en el simulador SPIM y ejecútalo.

1. Localiza el resultado de la suma. ¿Cuál ha sido? ¿El resultado obtenido es igual a 2.147.483.647 + 1?

2. Sustituye en el programa anterior la instrucción addiu por la instrucci ón addi. Borra los valores de la memoria, carga de nuevo el fichero fuente y vuelve a ejecutarlo (no en modo paso a paso). ¿Qué ha ocurrido al efectuar este cambio? ¿Por qué?

Las operaciones aritméticas en las que uno de los operandos es una constante aparecen con relativa frecuencia, p.e. para incrementar la variable índice en bucles del tipo for (int i ; i<n; i++ ) . Sin embargo, es más habitual encontrar instrucciones que requieran que ambos operandos sean variables (es decir, que el valor de ambos operandos no sea conocido en el momento en el que el programador escribe la instrucción). El siguiente programa presenta la instrucción subu rd , rs , rt que realiza una resta de números sin signo, donde los operandos fuente están en los registros rs y rt. En concreto, la instrucción subu rd , rs , rt realiza la operación rd <- rs - rt.

  oper-subu.s
1   .data # zona de datos
2 numero1: .word -2147483648 # Max. negativo representable en Ca2
3     # en hexadecimal 0x80000000
4 numero2: .word 1  
5 numero3: .word 2  
6      
7   .text # zona de instrucciones
8 main: lw $t0, numero1($0)  
9   lw $t1, numero2($0)  
10   subu $t0, $t0, $t1 # $t0<-$t0-$t1
11   lw $t1, numero3($0)  
12   subu $t0, $t0, $t1 # $t0<-$t0-$t1
13   sw $t0, numero3($0)  

Actividades (1 punto)

Carga el programa anterior en el simulador, ejecútalo paso a paso y contesta a las siguientes preguntas:

3. ¿Qué es lo que hace? ¿Qué resultado se almacena en la dirección de memoria etiquetada como numero3? ¿Es correcto?

4. ¿Se produce algún cambio si sustituyes las instrucciones subu por instrucciones sub? En caso de producirse, ¿a qué es debido este cambio?

Hasta ahora se han visto instrucciones para realizar sumas y restas. A continuaci ón se verá cómo realizar las operaciones de multiplicación y división. Dichas operaciones utilizan de forma implícita los registros HI y LO para almacenar el resultado de la operación correspondiente. En los ejercicios que aparecerán a continuación se descubrirá la utilidad de dichos registros y la informaci ón que se almacena en cada uno de ellos en función de la operación realizada.

  oper-mult.s
1   .data # zona de datos
2 numero1: .word 0x7fffffff # Max. positivo representable en Ca2
3 numero2: .word 16  
4   .space 8  
5      
6   .text # zona de instrucciones
7 main: lw $t0, numero1($0)  
8   lw $t1, numero2($0)  
9   mult $t0, $t1 # HI, LO<-$t0x$t1
10   mfhi $t0 # $t0<-HI
11   mflo $t1 # $t1<-LO
12   sw $t0, numero2+4($0) # M[ numero2+4] <- $t0
13   sw $t1, numero2+8($0) # M[ numero2+8] <- $t0

Actividades (1 punto)

Carga el programa anterior en el simulador, ejecútalo paso a paso y contesta a las siguientes preguntas: 5. La instrucción mult $t0 , $t1 almacena el resultado en los registros HI y LO. ¿Qué instrucciones se utilizan para recuperar dicha información?

6. ¿Qué resultado se obtiene después de ejecutar mult $t0 , $t1? ¿En qué registros se almacena el resultado? ¿Cuál es este resultado? ¿Por qué se utilizan dos palabras?

7. Observa que dos de las instrucciones del programa anterior utilizan la suma de una etiqueta y una constante para determinar el valor del dato inmediato. ¿Qué instrucciones son?

8. Utilizando como guía el programa anterior, crea uno nuevo que divida 10 entre 3 y almacene el cociente y el resto en las dos palabras siguientes a la dirección de memoria referencia por la etiqueta numero2. Para ello, ten en cuenta que la instrucción de división entera, divrs , rt, divide rs entre rt y almacena el resto en HI y el cociente en LO.

Operaciones lógicas

El procesador MIPS32 proporciona un conjunto de instrucciones que permite realizar operaciones lógicas del tipo AND, OR, XOR, entre otras. Se debe tener en cuenta que las operaciones lógicas, aunque toman como operandos dos palabras, actúan bit a bit. Así, por ejemplo, la AND de dos palabras genera como resultado una palabra en la que el bit 0 es la AND de los bits 0 de los operandos fuente, el bit 1 es la AND de los bits 1 de los operandos fuente, y así sucesivamente. Se va a ver como ejemplo de las instrucciones que implementan las operaciones lógicas, la instrucción que implementa la operación AND.

La instrucción andi rs , rt ,Inm realiza la operación lógica AND bit a bit del número almacenado en rt y el número almacenado en el campo Inm de la propia instrucción. Puesto que el campo destinado al almacenamiento del número inmediato es de 16 bits y el operando ha de tener 32 bits, es necesario extender la información proporcionada en Inm de 16 a 32 bits. Esta extensión se realiza en las operaciones lógicas colocando a 0 los 16 bits más significativos. Por ejemplo, el dato inmediato de 16 bits 0xfffe cuando se utiliza como operando de una operación lógica, se extiende al valor de 32 bits 0x0000 fffe, que en binario (complemento a 2 )es: 00000000 00000000 11111111 11111110.

  oper-and.s
1   .data # zona de datos
2 numero: .word 0x1234567  
3   .space 4  
4      
5   .text # zona de instrucciones
6 main: lw $t0, numero($0)  
7   andi $t1, $t0, 0xfffe # 0xfffe es en binario :
8     # 1111 1111 1111 1110
9   sw $t1, numero+4($0) # HI, LO<-$t0x$t1

Actividades (2 puntos)

9. Carga el anterior programa en el simulador y ejecútalo. ¿Qué valor, expresado en hexadecimal, se almacena en la posición de memoria numero+4? ¿Coincide con el resultado calculado en la explicación anterior?

10. Modifica el código para que almacene en numero+4 el valor obtenido al conservar tal cual los 16 bits más significativos del dato almacenado en numero, y poner a cero los 16 bits menos significativos, salvo el bit cero, que también debe conservar su valor original. (Pista: La instrucción and rd, rs , rt realiza la AND lógica de los registros rs y rt y almacena el resultado en rd.)

Operaciones de desplazamiento

El procesador MIPS32 también proporciona instrucciones que permiten desplazar los bits del número almacenado en un registro un determinado número de posiciones a la derecha o a la izquierda. 42 Operaciones aritméticas, lógicas y de desplazamiento El siguiente programa presenta la instrucción de desplazamiento aritmético a derechas (shift right arithmetic). La instrucción, sra $t1 , $t0 , 4, desplaza el valor almacenado en el registro $t0, 4 bits a la derecha conservando su signo y almacena el resultado en $t1.

  oper-sra.s
1   .data # zona de datos
2 numero: .word 0xffffff41  
3      
4   .text # zona de instrucciones
5 main: lw $t0, numero($0)  
6   sra $t1, $t0, 4 # $t1 <- $t0>>4

Actividades (2 puntos)

11. Carga el programa anterior en el simulador y ejecútalo, ¿qué valor se almacena en el registro $t1? ¿Qué se ha hecho para conservar el signo del número original en el desplazado? Modifica el programa para comprobar su funcionamiento cuando el número que se debe desplazar es positivo.

12. Modifica el programa propuesto originalmente para que realice un desplazamiento de 3 bits. Como se puede observar, la palabra original era 0xffff ff41 y al desplazarla se ha obtenido la palabra 0xffff ffe8. Representa ambas palabras en binario y comprueba si la palabra 0xffff ffe8 corresponde realmente al resultado de desplazar 0xffff ff41 3 bits a la derecha conservando su signo.

13. La instrucción srl, desplazamiento lógico a derechas (shift right logic), también desplaza a la derecha un determinado número de bits el valor indicado. Sin embargo, no tiene en cuenta el signo y rellena siempre con ceros. Modifica el programa original para que utilice la instrucción srl en lugar de la sra ¿Qué valor se obtiene ahora en $t1?

14. Modifica el código para desplazar el contenido de numero 2 bits a la izquierda. (Pista: La instrucción de desplazamiento a izquierdas responde al nombre en inglés de shift left logic)

15. Desplazar n bits a la izquierda equivale a una determinada operación aritmética (siempre que no se produzca un desbordamiento). ¿A qué operación aritmética equivale? ¿Según esto, desplazar 1 bit a la izquierda a qué equivale? ¿Y desplazar 2 bits?

16. Por otro lado, desplazar n bits a la derecha conservando el signo también equivale a una determinada operación aritmética. ¿A qué operación aritmética equivale? (Nota: si el número es positivo el desplazamiento corresponde siempre a la operación indicada; sin embargo, cuando el número es negativo, el desplazamiento no produce siempre el resultado exacto.)