Lab 04

Anuncio
Cuarta Experiencia.
Laboratorio de Estructuras de Computadores
02/2001
Preparación previa.
Estructuras dinámicas de datos. Solicitación de memoria.
Se estudia una lista simplemente enlazada, ésta está formada por un conjunto de nodos.
Cada nodo es una estructura(struct en C) formada por un puntero y un entero.
/* Declaración del nodo para la lista enlazada */
struct node {
struct node *next;
/* puntero al siguiente nodo */
int value;
/* espacio para almacenar un valor entero */
};
Los nodos se enlazan empleando el campo next(próximo) del nodo. El último nodo de la
lista tiene un valor nulo(valor cero) en el campo next.
Se emplea la lista para mantener un conjunto ordenado de enteros. Es decir, el entero más
negativo está almacenado en el primer nodo de la lista, y el positivo mayor en el último
nodo de la lista.
En los apuntes de clases existe una breve introducción al lenguaje C, en el que se estudia
una lista simplemente enlazada.
El siguiente programa en C, ilustra las funciones:
newnode que crea una nueva instancia de un nodo y lo coloca en el lugar correcto de la
lista.
printlist que imprime la secuencia de valores almacenados en la lista.
main: prueba las funciones anteriores.
Además se emplea una variable estática list, desde la cual se cuelga la lista obtenida en
forma dinámica. En esta situación se está obligado a emplear un puntero.
En el momento de la compilación y carga del programa en memoria, sólo se tiene el
espacio para la variable list. Luego, durante la ejecución, el espacio dinámico se asocia al
puntero list.
static struct node *list = 0; /* puntero al primer nodo de la lista */
/* Mantiene la lista de enteros ordenada. Colocando cada nuevo elemento en su lugar*/
void newnode (int value) {
struct node *temp = ( struct node *) malloc(sizeof(*temp));
/* Nótese que el tamaño en bytes se calcula con: sizeof(*temp) == sizeof(struct node) */
struct node *aptr, *bptr;
temp->value = value;
/* enlaza el item en el lugar correcto */
aptr = ( struct node *) &list;
/* el cast es necesario, sino habría tipos incompatibles */
bptr = list;
Laboratorio de Estructuras de Computadores.
Lab04
14-08-2001
1
while ((bptr!=0) && (bptr->value < value)) {
aptr = bptr;
bptr = bptr->next;
}
aptr->next = temp;
temp->next = bptr;
}
/* Imprime los enteros de la lista. */
void printlist(void) {
struct node *ptr;
ptr = list;
while (ptr != 0) {
printf("%d\n", ptr->value);
ptr = ptr->next;
}
}
/* La función principal prueba la función newnode. */
int main (void) {
newnode(5);
newnode(1); lista
newnode(0);
newnode(6);
newnode(-1);
newnode(10);
-1
0
1
5
6
10
printlist();
}
El resultado correcto de la impresión debe ser:
-1
0
1
5
6
10
# En el código assembler de malloc se emplea un llamado al sistema.
# Esta versión deja la zona iniciada con puros unos.
# a0 debe ser el tamaño en bytes que se asignará.
# en v0 se retorna un puntero a la zona asignada.
Laboratorio de Estructuras de Computadores.
Lab04
14-08-2001
2
malloc:
# extend memory size
#
li $v0,9
# código para sbrk
syscall
# retorna una zona iniciada con ceros
#
beq
addiu
addu
ori
sb
j
l1:
listo: jr $ra
$a0,$0,listo
$a0,$a0,-1
$t0,$a0,$v0
$t1, $t1, 0xff
$t1,0($t0)
l1
# mientras queden en la zona
# a0-# t0 apunta a un byte de la zona
# t1 = 0xFF
# setea el byte con puros unos
# continue
# el valor de v0 es el retorno del syscall brk
En el Laboratorio.
• Compilar y ejecutar en C. Si es necesario, agregar algunos printf para observar
variables; o bien, correr paso a paso, empleando un depurador y observando
variables(inspect o watch).
•
Escribir el programa en assembler MIPS. Ejecutarlo en SPIM observando la
ejecución de las rutinas.
•
Empleando lcc, compilar el texto en C, e introducir las rutinas assembler para
malloc y printf.
Laboratorio de Estructuras de Computadores.
Lab04
14-08-2001
3
Descargar