Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- extern malloc
- section .rodata
- ; Acá se pueden poner todas las máscaras y datos que necesiten para el ejercicio
- %define INDEX_SIZE 2
- %define POINTER_SIZE 8
- %define ITEM_STRENGTH_OFFSET 20
- %define ITEM_DURABILITY_OFFSET 24
- section .text
- ; Marca un ejercicio como aún no completado (esto hace que no corran sus tests)
- FALSE EQU 0
- ; Marca un ejercicio como hecho
- TRUE EQU 1
- ; Marca el ejercicio 1A como hecho (`true`) o pendiente (`false`).
- ;
- ; Funciones a implementar:
- ; - es_indice_ordenado
- global EJERCICIO_1A_HECHO
- EJERCICIO_1A_HECHO: db TRUE ; Cambiar por `TRUE` para correr los tests.
- ; Marca el ejercicio 1B como hecho (`true`) o pendiente (`false`).
- ;
- ; Funciones a implementar:
- ; - indice_a_inventario
- global EJERCICIO_1B_HECHO
- EJERCICIO_1B_HECHO: db TRUE ; Cambiar por `TRUE` para correr los tests.
- ;; La funcion debe verificar si una vista del inventario está correctamente
- ;; ordenada de acuerdo a un criterio (comparador)
- ;; bool es_indice_ordenado(item_t** inventario, uint16_t* indice, uint16_t tamanio, comparador_t comparador);
- ;; Dónde:
- ;; - `inventario`: Un array de punteros a ítems que representa el inventario a
- ;; procesar.
- ;; - `indice`: El arreglo de índices en el inventario que representa la vista.
- ;; - `tamanio`: El tamaño del inventario (y de la vista).
- ;; - `comparador`: La función de comparación que a utilizar para verificar el
- ;; orden.
- ;;
- ;; Tenga en consideración:
- ;; - `tamanio` es un valor de 16 bits. La parte alta del registro en dónde viene
- ;; como parámetro podría tener basura.
- ;; - `comparador` es una dirección de memoria a la que se debe saltar (vía `jmp` o
- ;; `call`) para comenzar la ejecución de la subrutina en cuestión.
- ;; - Los tamaños de los arrays `inventario` e `indice` son ambos `tamanio`.
- ;; - `false` es el valor `0` y `true` es todo valor distinto de `0`.
- ;; - Importa que los ítems estén ordenados según el comparador. No hay necesidad
- ;; de verificar que el orden sea estable.
- global es_indice_ordenado
- es_indice_ordenado:
- ; Prologo (uso volátiles porque vamos a llamar funciones externas en varias iteraciones.)
- push rbp
- mov rbp, rsp
- sub rsp, 16 ; Solo uso 8, pero los otros 8 son para mantenerse alineados, ya que uso 4 registros volatiles
- push r15
- push r14
- push r13
- push r12
- mov r15, rdi ; R15 = inventario
- mov r14, rsi ; R14 = indice
- mov r13, rdx ; R13 = tamaño
- dec r13 ; Decremento R13 porque queremos interar Tamaño - 1 veces
- xor r12, r12 ; R12 = contador
- mov [rbp-8], rcx ; RBP-8, comparador
- .loop:
- cmp r12, r13 ; Reviso si el contador y el tamaño-1 son iguales
- je .en_true ; Si lo son, termino en true, ya que todos los elementos fueron revisados
- xor rdx, rdx ; Vacío rdx y r8 por si tienen basura
- xor r8, r8
- mov dx, word [r14] ; Cargo el indice en dx
- mov r8w, word [r14 + 2] ; Cargo el proximo indice en r8w, para comparar
- mov rdi, [r15 + rdx*POINTER_SIZE] ; En rdi, cargo el item del inventario en el indice de cx
- mov rsi, [r15 + r8*POINTER_SIZE] ; En rsi, cargo el item del inventario que le sigue en la jerarquía
- call [rbp-8] ; Llamo al comparador, solo se que en rax me queda un 1 o un 0.
- cmp ax, 0 ; Si ax es 0, la comparación no fue esperada, entonces el indice no está ordenado
- je .en_false ; Entonces terminamos en false
- ; Caso contrario, continuo iterando.
- add r14, INDEX_SIZE ; +2 a r14, así vemos el próximo indice.
- inc r12 ; +1 al contador
- jmp .loop ; Seguimos iterando
- .en_false:
- mov rax, 0 ; Pongo 0 (false en rax) y termino
- jmp .fin ; Uso jmp para saltearme la próxima label (en_true)
- .en_true:
- mov rax, 1 ; Pongo 1 (true) en rax y termino
- .fin:
- ; Epilogo
- pop r12
- pop r13
- pop r14
- pop r15
- add rsp, 16
- mov rsp, rbp
- pop rbp
- ret
- ;; Dado un inventario y una vista, crear un nuevo inventario que mantenga el
- ;; orden descrito por la misma.
- ;; La memoria a solicitar para el nuevo inventario debe poder ser liberada
- ;; utilizando `free(ptr)`.
- ;; item_t** indice_a_inventario(item_t** inventario, uint16_t* indice, uint16_t tamanio);
- ;; Donde:
- ;; - `inventario` un array de punteros a ítems que representa el inventario a
- ;; procesar.
- ;; - `indice` es el arreglo de índices en el inventario que representa la vista
- ;; que vamos a usar para reorganizar el inventario.
- ;; - `tamanio` es el tamaño del inventario.
- ;;
- ;; Tenga en consideración:
- ;; - Tanto los elementos de `inventario` como los del resultado son punteros a
- ;; `ítems`. Se pide *copiar* estos punteros, **no se deben crear ni clonar
- ;; ítems**
- global indice_a_inventario
- indice_a_inventario:
- ; Prologo
- push rbp
- mov rbp, rsp
- sub rsp, 16 ; Solo uso 8, pero los otros 8 son para mantenerse alineados, ya que uso 4 registros volatiles
- push r15
- push r14
- push r13
- push r12
- mov r15, rdi ; Muevo el inventario a r15
- mov r14, rsi ; Muevo el indice a r14
- mov r13, rdx ; Muevo el tamaño a r13
- xor r12, r12 ; Creo un contador en r12
- mov rdi, POINTER_SIZE ; Me traigo el tamaño de puntero a rdi
- imul rdi, r13 ; y lo multiplico por el tamaño para ver cuanta memoria alocar
- call malloc ; Dejo en rax un item_t** nuevo, para devolver
- mov [rbp-8], rax ; Guardo en stack el puntero, ya que voy a incrementar rax
- .loop:
- cmp r12, r13 ; Comparo mi contador con mi tamaño.
- je .end ; Si son iguales, terminamos de armar nuestro inventario
- xor rdx,rdx ; Vacío rdx en caso de que tenga basura
- mov dx, word [r14] ; Cargo el indice en dx
- mov rdi,[r15 + rdx*POINTER_SIZE] ; Busco inventario[indice] con indice en dx
- mov [rax], rdi ; Muevo el puntero a rax para posicionarlo en la lista
- inc r12 ; +1 al contador
- add rax, POINTER_SIZE ; +8 a rax, para poder agregar el proximo puntero
- add r14, INDEX_SIZE ; +2 a r14, así vemos el próximo indice.
- jmp .loop
- .end:
- ; Muevo nuestro puntero guardado a rax
- mov rax, [rbp-8]
- ; Epílogo
- pop r12
- pop r13
- pop r14
- pop r15
- add rsp, 16
- mov rsp, rbp
- pop rbp
- ret
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement