Quiz 1 Laboratorio de Estructura de Computadores 02/2004 Considere el siguiente programa en C: #include<stdio.h> #define MAX 27 typedef struct nodo { char letra; struct nodo *anterior; struct nodo *proxima; } LETRA, *PLETRA; LETRA palabra[MAX]; void f1(char x,int c) { PLETRA v; int i; if (MAX==0) return; v=palabra; v->anterior=0; v->proxima=0; for(i=0; (i<c)&&(i<MAX); i++) { v->proxima=&palabra[i]; palabra[i].letra=x+i; palabra[i].proxima=0; palabra[i].anterior=v; v=&palabra[i]; } } void f2(PLETRA p) { do putchar(p->letra); while(p++->proxima); } void f3(PLETRA p) { PLETRA v; char y; v=p; while(v->proxima) v++; while(p<v) { y=p->letra; p->letra=v->letra; v->letra=y; p=p->proxima; v=v->anterior; } } void main() { char l; int n; printf("\n Ingrese una letra : \n"); l=getchar(); printf("\n Ingrese un numero : \n"); scanf("%d",&n); f1(l,n); f2(palabra); putchar('\n'); f3(palabra); f2(palabra); putchar('\n'); } a) ¿Qué valores toma el arreglo palabra después de la invocación de la función f1? Explique. b) ¿Qué hace la función f2? ¿Es una función con paso por valor o por referencia? c) ¿Qué instrucción(es) modifica(n) el contenido del arreglo palabra durante la invocación de la función f3? Explique. d) En el principio del programa en C se define una estructura. ¿Cuántos bytes ocupa dicha estructura? Justifique su resultado. Genere el correspondiente código asembler MIPS utilizando el compilador lcc. e) ¿En qué sección del código se define el arreglo global palabra? Explique las directivas que allí aparecen. f) Identifique claramente la sección de código que implementa la sentencia while de la función f2. ¿Dónde se implementa la condición de dicha iteración? g) Cargue el listado assembler generado en SPIM. Se produce un error. Identifique, en dicho listado la causa del error y corríjalo. Explique. h) Identifique claramente las secciones del código donde se guardan los strings de los mensajes que aparecen en main. Cambie dichas secciones por una única directiva .asciiz. • • • a), b), c) y d) 1 punto. e), f), g) y h) 1 punto. Entregar resultados ESCRITOS . Interrogación ORAL 1 punto. Ayuda: Puede bajar el código http://alumnos.elo.utfsm.cl/~rlar/quiz1/q1c.c desde Solución. a) La función f1(l,n) rellena un arreglo de la estructura LETRA, de 27 elementos, con n letras a partir del carácter l ingresado. b) Es una función con paso por referencia y permite escribir el arreglo con los n elementos ingresados por f1. c) La instrucciones que están dentro del while: p->letra=v->letra; v->letra=y; d) Dependiendo de si el char de la estructura queda alineado ó no, el tipo LETRA ocupa 12 bytes. Este resultado se puede ver también en el listado compilado en MIPS considerando que el arreglo del tipo LETRA contiene 27 elementos. e) Las directivas que definen el arreglo son: .globl palabra .comm palabra,324 Se puede ver el tamaño en bytes reservado para el arreglo. La directiva .comm se utiliza para indicar que corresponde a una variable no inicializada. f) La sección del código assembler que implementa el while de la función f2 corresponde a: move $30,$4 L.12: lb $4,($30) jal putchar L.13: move $24,$30 la $30,12($24) lw $24,8($24) bne $24,$0,L.12 Donde la condición se implementa en la instrucción bne. g) El error se produce porque el compilador lcc agrega unas instrucciones de corrimiento lógico y aritmético con un argumento mal calculado. La solución consiste en cambiar estas instrucciones manualmente: sll $15,$4,8*(4-1); sra $15,$15,8*(4-1) cambiar por sll $15,$4,24; sra $15,$15,24 h) El siguiente label corresponde a texto de la primera instrucción printf: L.23: .byte 10 .byte 32 .byte 73 .byte 110 .byte 103 .byte 114 .byte 101 .byte 115 .byte 101 .byte 32 .byte 117 .byte 110 .byte 97 .byte 32 .byte 108 .byte 101 .byte 116 .byte 114 .byte 97 .byte 32 .byte 58 .byte 32 .byte 10 .byte 0 Puede ser reemplazado por: .asciiz “\n Ingrese una letra : \n” El siguiente label corresponde a texto de la segunda instrucción printf: L.24: .byte 10 .byte 32 .byte 73 .byte 110 .byte 103 .byte 114 .byte 101 .byte 115 .byte 101 .byte 32 .byte 117 .byte 110 .byte 32 .byte 110 .byte 117 .byte 109 .byte 101 .byte 114 .byte 111 .byte 32 .byte 58 .byte 32 .byte 10 .byte 0 Puede ser reemplazado por: .asciiz “\n Ingrese un numero : \n” Finalmente el label siguiente contiene el string asociado a la instrucción scanf: L.25: .byte 37 .byte 100 .byte 0 que puede ser reemplazado por: .asciiz “%d”