author | Rodrigo Campos
<rodrigo@sdfg.com.ar> 2011-04-08 03:52:31 UTC |
committer | Rodrigo Campos
<rodrigo@sdfg.com.ar> 2011-04-08 04:01:36 UTC |
parent | 891bf1194ee8186eab9446b25c99745000de0305 |
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