Contents
Al finalizar esta práctica el estudiante será capaz de:
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
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.
Para poder sacar el máximo partido a la sesión de laboratorio, lee atentamente el siguiente texto y prepara EN UNA HOJA APARTE las respuestas a los ejercicios.
En esta sección se trata la estructura condicional if. Esta estructura evalúa una condición y si se cumple, ejecuta un determinado código; en caso contrario, no hace nada. El programa siguiente intenta evitar que se realice una división por cero (lo que generaría una excepción). Para ello, comprueba si el divisor es distinto de cero antes de realizar la división, y en caso contrario, simplemente devuelve un 0 como resultado. En concreto, el programa propuesto almacena en la variable res el cociente de la división entera de dos números, dato1 y dato2, o un 0 si dato2 es igual a 0.
1 int main ( int argc, char** arg v ) {
2 int dato1=40;
3 int dato2=30;
4 int res;
5
6 res=0;
7 if (dato2!=0) {
8 res=dato1/dato2;
9 }
10 }
Una versión en ensamblador del MIPS32 del anterior programa en C podría ser la siguiente:
cotrol-if.s 1 .data # zona de datos 2 dato1: .word 40 3 dato2: .word 30 4 res: .space 4 5 6 .text # zona de instrucciones 7 main: lw $t1, dato1($0) # Carga M[dato1] en $t1 8 lw $t2, dato2($0) # Carga M[dato2] en $t2 9 and $t0, $0, $0 # $t0<-0 10 si: beq $t2, $0, finsi 11 entonces: div $t1, $t2 # $t1/$t2 12 mflo $t0 # Almacena LO en $t0 13 finsi: sw $t0, res($0) # Almacena $t0 en res
Ahora se va a ver cómo se implementa en ensamblador la estructura de control condicional if - else. Crea un fichero con el siguiente fragmento de código que contiene una estructura de control de dicho tipo.
cotrol-if_else.s 1 .data # zona de datos 2 dato1: .word 30 3 dato2: .word 40 4 res: .space 4 5 6 .text # zona de instrucciones 7 main: lw $t1, dato1($0) # Carga dato1 en $t1 8 lw $t2, dato2($0) # Carga dato2 en $t2 9 si: bge $t1, $t2, sino # Si $t1>=$t2 ir a sino 10 entonces: sw $t1, res($0) # Almacena $t1 en res 11 j finsi # Ir a finsi 12 sino: sw $t2, res($0) # Almacena $t2 en res 13 finsi:
1 int main ( int argc, char** arg v ) {
2 int dato1=30;
3 int dato2=40;
4 int res;
5
6 if (dato1<=dato2){
7 res=dato1-dato2;
8 }else{
9 res=dato2-dato1;
10 }
11 }
El siguiente programa en C utiliza una estructura de control while para descubrir el número de caracteres de una cadena dada (que termina con el carácter nulo).
1 int main( int argc, char** arg v ) {
2 char cadena[ ] = Hola, ¿como estas? ; //Faltas
3 int n =0;
4
5 while ( cadena [n]!=0 ) {
6 n++;
7 }
8 }
Una versión en ensamblador del MIPS32 del anterior programa en C podr´ýa ser la siguiente:
cotrol-while.s 1 .data # zona de datos 2 cadena: .asciiz "hola, como estas" 3 .align 2 4 n: .space 4 5 6 .text # zona de instrucciones 7 main: andi $t0, $t0, 0 # $t0<-0 8 mientras: lb $t1, cadena($t0) # $t1<-M[cadena+$t0] (un byte) 9 beq $t1, $0, finmientras # Si $t1>==0 ir a finmientras 10 j mientras 11 finmientras: sw $t0,n($0) # Almacena $t0 en n
La estructura de control repetitiva for se diferencia de la while en que el número de iteraciones de la primera es conocido de antemano. Así pues, se hace necesario el uso de una variable que almacene el número de iteraciones que se van realizando para así poder compararlo con el número de iteraciones que deben realizarse. La variable que almacena dicha cuenta recibe el nombre de contador. Generalmente, un contador se suele inicializar con el valor 0 e incrementar de 1 en 1 hasta que alcanza el número total de iteraciones menos 1.
El siguiente ejemplo muestra un programa en C que acumula los elementos de un vector V en una variable llamada res. Para ello, utiliza una estructura condicional for y un contador llamado i. :
1 int main ( int argc, char** argv ) {
2 int V[]={6, 7, 8, 9, 10, 1};
3 int n =6;
4 int i;
5 int res;
6
7 res=0;
8 for (i=0; i<n; i++) {
9 res=res+V[i];
10 }
11 }
Una versión en ensamblador del MIPS32 del anterior programa en C podría ser la siguiente:
cotrol-while.s 1 .data # zona de datos 2 vector: .word 6, 7, 8, 9, 10, 1 3 n: .word 6 4 res: .space 4 5 6 .text # zona de instrucciones 7 main: la $t2, vector # $t2<-dirección de vector 8 and $t3, $0, $0 # t3 <-0 9 and $t0, $0, $0 # t0 <-0 10 lw $t1, n($0) # t1 <-Mem[n] 11 j mientras 12 para: bge $t0, $t1, finpara # Si $t0>=$t1 Salta a finpara 13 add $t3, $t3, $t4 14 addi t2, $t2, 4 15 addi $t0, $t0, 1 16 j para 17 finpara: sw $t3,res($0) # Almacena $t3 en res