git » orga2-tp1.git » commit cb3f549

Implementar "insertar"

author Rodrigo Campos
2011-04-08 03:52:31 UTC
committer Rodrigo Campos
2011-04-08 04:01:36 UTC
parent 891bf1194ee8186eab9446b25c99745000de0305

Implementar "insertar"

Signed-off-by: Rodrigo Campos <rodrigo@sdfg.com.ar>

bintree.asm +162 -0

diff --git a/bintree.asm b/bintree.asm
index e69de29..5dc4075 100644
--- a/bintree.asm
+++ b/bintree.asm
@@ -0,0 +1,162 @@
+
+; offsets y size del struct nodo_t
+; los offsets son relativos al comienzo del nodo
+%define sizeof_nodo 18
+%define off_id 0
+%define off_nom 2
+%define off_puntaje 6
+%define off_izq 10
+%define off_der 14
+
+extern malloc
+
+section .data
+msg: db 'hola', 0
+
+
+section .text
+global test_write, test_write2, insertar
+
+test_write:
+        push ebp
+        mov ebp, esp
+        push edi
+        push esi
+        push ebx
+
+	mov ebx, [ebp + 8]
+	mov ebx, 0x0
+	%define .nodoId [ebx]
+	%define .nodoNom [ebx + 2]
+	%define .nodoPun [ebx + 6]
+
+	mov byte .nodoId, 0x8
+	mov ecx, msg
+	mov dword .nodoNom, ecx
+	mov dword .nodoPun, 0x1
+
+	pop ebx
+	pop esi
+	pop edi
+	pop ebp
+	ret
+
+insertar:
+        push ebp
+        mov ebp, esp
+        push edi
+        push esi
+        push ebx
+
+	; alocamos memoria para un nodo
+	; XXX: lo hacemos antes de copiar cosas a los registros porque, por la
+	; convencion C, solo protege edi, esi y ebx
+	mov esi, sizeof_nodo
+	push esi
+	call malloc
+	add esp, 4
+
+	; si malloc devuelve 0, no tenemos nada para hacer
+	cmp eax, 0
+	je .fin
+
+	mov ebx, [ebp + 8] ; nodo **arbol, 4bytes
+	%define .arbol [ebx] ; nodo *arbol, 4bytes
+	%define .nom [ebp + 12] ; char *nombre, 4bytes
+	mov dx, [ebp + 16] ; short id, 2 bytes
+	%define .id dx
+	mov edi, [ebp + 20] ; float puntaje, 4bytes
+	%define .punt edi
+
+	%define .nId [eax + off_id]
+	%define .nNom [eax + off_nom]
+	%define .nPuntaje [eax + off_puntaje]
+	%define .nIzq [eax + off_izq]
+	%define .nDer [eax + off_der]
+
+	; Asignamos los parametros al nodo creado
+	mov .nId, .id
+	mov .nPuntaje, .punt
+	mov dword .nIzq, 0
+	mov dword .nDer, 0
+	; pisamos dx ahora que ya lo copiamos
+	mov edx, .nom
+	mov .nNom, edx
+
+	; Si es el arbol vacio (apunta a NULL), entonces devolvemos el arbol que tiene solo este nodo
+	; Si no es el arbol vacio, insertamos el nodo
+	cmp dword .arbol, 0
+	jne .insertar
+	mov [ebx], eax
+	jmp .fin
+
+.insertar:
+	push eax ; el nodo que creamos, 2º param
+	push ebx ; nodo **arbol, 1º param
+	call buscar_e_insertar
+	add esp, 8
+
+.fin:
+	pop ebx
+	pop esi
+	pop edi
+	pop ebp
+	ret
+
+
+; void buscar_e_insertar(nodo **arbol, nodo *n);
+; asume que *arbol != NULL
+buscar_e_insertar:
+
+        push ebp
+        mov ebp, esp
+        push edi
+        push esi
+        push ebx
+
+	mov ebx, [ebp + 8] ; nodo **arbol; 4 bytes
+	mov ebx, [ebx] ; nodo *arbol
+	mov edi, [ebp + 12]; nodo* n; 4bytes
+
+	; ponemos el id en ax
+	mov ax, [edi + off_id]
+
+	; invariante: en ebx guardamos el puntero a nodo que vamos iterando
+	; y en ecx el puntero al nodo padre del nodo actual
+	mov ecx, 0
+
+.loop:
+	cmp dword ebx, 0
+	je .insertar
+	mov ecx, ebx
+
+	; comparamos el id del nodo a insertar con el id del actual
+	cmp word ax, [ebx + off_id]
+	; XXX: por que no andan como quiero los conditional moves ?
+	;cmovl ebx, [ebx + off_izq]
+	;cmovge ebx, [ebx + off_der]
+	jle .loopIz
+	mov ebx, [ebx + off_der]
+	jmp .loop
+.loopIz:
+	mov ebx, [ebx + off_izq]
+	jmp .loop
+
+
+.insertar:
+	; nos fijamos si tenemos que insertar en el subarbol izquierdo o en el subarbol derecho
+	; usamos ecx porque siempre salimos con ebx en NULL
+	cmp ax, [ecx + off_id]
+	jle .insertarIz
+	mov [ecx + off_der], edi
+	je .fin
+.insertarIz:
+	mov [ecx + off_izq], edi
+	je .fin
+
+.fin:
+	pop ebx
+	pop esi
+	pop edi
+	pop ebp
+	ret