Parcial del 16/11/06 (Organización del Computador II)

De Cuba-Wiki
Saltar a: navegación, buscar
Back.png 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;
}