Parcial del 16/11/06 (Organización del Computador II)
Revisión del 02:53 5 oct 2007 de Profeta (discusión | contribuciones)
![]() |
Volver a la página de la materia |
Enunciado[editar]
Dada una lista de puntos en aplicar la transformacion T a cada nodo eliminando los nodos cuyo resultado sea 0. El resultado debe guardarse en el campo res del nodo correspondiente. Si res es 0, el nodo debe eliminarse de la lista.
T(x,y) = x * sen(alfa) * beta - y * cos(alfa) + gama struct NodoL { double x, y, res; NodoL *prox; } struct Coefs { double alfa, beta, gama; } void AplicarT(NodoL **pl, Coefs *pc); void free(void*);
Resolucion[editar]
Archivo ASM[editar]
parcial.asm
; Definiciones para Windows %ifdef win32 %define AplicarT _AplicarT %define free _free %endif ; Tal como le prometimos a C, aca estan las funciones global AplicarT ; El malloc lo tengo definido afuera extern free ; Comienzo del codigo section .text ; Defines para hacerme la vida mas facil a la hora de apuntar a los miembros de las estructuras %define x 0 %define y 8 %define res 16 %define prox 24 %define alfa 0 %define beta 8 %define gama 16 ;------------------------------------------------------------------- ; Macros ;------------------------------------------------------------------- ; Inicio del stack frame %macro SF_ini 0 push ebp mov ebp, esp push esi push edi push ebx %endmacro ; Fin del stack frame %macro SF_fin 0 pop ebx pop edi pop esi pop ebp ret %endmacro ;------------------------------------------------------------------- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; void AplicarT(NodoL **pl, Coefs *pc); ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; AplicarT: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ebx = actual->prox ; edx = pc ; edi = puntero a actual ; esi = puntero al puntero de actual ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SF_ini ; Seteo esi (ppactual) y si era nula la lista termino aca nomas mov esi, [ebp + 8] cmp esi, 0 je _fin_AplicarT ; Seteo edi (pactual) mov edi, [esi] ; Seteo edx (pc) mov edx, [ebp + 12] ; Inicializo la FPU finit ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Cargo en la pila de FPU las constantes ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; fldz fld qword [edx + gama] fld qword [edx + alfa] fsincos ;st3 = 0.0 ;st2 = gama ;st1 = sin(alfa) ;st0 = cos(alfa) fld qword [edx + beta] fmul st0, st2 ;st4 = 0.0 ;st3 = gama ;st2 = sin(alfa) ;st1 = cos(alfa) ;st0 = sin(alfa) * beta ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Bucle principal _bucle: fld qword [edi + x] fmul st0, st1 ;st5 = 0.0 ;st4 = gama ;st3 = sin(alfa) ;st2 = cos(alfa) ;st1 = sin(alfa) * beta ;st0 = x * sin(alfa) * beta fld qword [edi + y] fmul st0, st3 ;st6 = 0.0 ;st5 = gama ;st4 = sin(alfa) ;st3 = cos(alfa) ;st2 = sin(alfa) * beta ;st1 = x * sin(alfa) * beta ;st0 = y * cos(alfa) fsubp st1, st0 fadd st0, st4 ;st5 = 0.0 ;st4 = gama ;st3 = sin(alfa) ;st2 = cos(alfa) ;st1 = sin(alfa) * beta ;st0 = x * sin(alfa) * beta - y * cos(alfa) + gama ; Guardo el valor y comparo si no era cero mov ebx, [edi + prox] fcomi st0, st5 fstp qword [edi + res] jne _siguiente _borro: ; Cambio la direccion del anterior para que apunte al que le seguia al que recien borre mov dword [esi], ebx ; Borro el nodo de memoria push edi call free add esp, 4 _siguiente: ; Actualizo los punteros mov esi, edi add esi, prox mov edi, ebx ; Verifico si no termine cmp edi, 0 jne _bucle _fin_bucle _fin_AplicarT: ; Limpio la FPU emms SF_fin ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Archivo C[editar]
main.c
#include <stdio.h> #include <stdlib.h> #define PI 3.1415926535897932384626433832795 /* Estructura de un nodo */ struct NodoL { double x, y, res; struct NodoL *prox; }; /* Estructura de coeficientes */ struct Coefs { double alfa, beta, gama; }; /* Le juro a C que defino la funcion afuera */ extern void AplicarT(struct NodoL **pl, struct Coefs *pc); /* Muestra un NGde por pantalla */ void MostrarLista(struct NodoL **pl) { struct NodoL *actual = *pl; while(actual != NULL) { printf("<%f, %f, %f>\n", actual->x, actual->y, actual->res); actual = actual->prox; } } /************* Punto de entrada ****************/ int main(int argc, char *argv[]) { struct NodoL *tercero = malloc(sizeof(struct NodoL)); tercero->x = 1; tercero->y = -1; tercero->prox = 0; struct NodoL *segundo = malloc(sizeof(struct NodoL)); segundo->x = 2; segundo->y = -1; segundo->prox = tercero; struct NodoL *primero = malloc(sizeof(struct NodoL)); primero->x = 1; primero->y = 10; primero->prox = segundo; struct NodoL **lista = &primero; struct Coefs *pc = malloc(sizeof(struct Coefs)); pc->alfa = PI/4; pc->beta = 2; pc->gama = 10; printf("Lista pre-aplicar:\n"); MostrarLista(lista); AplicarT(lista, pc); printf("Lista post-aplicar:\n"); MostrarLista(lista); return 0; }