Advertisement
tievo

Untitled

Nov 17th, 2024
146
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. extern malloc
  2.  
  3. section .rodata
  4. ; Acá se pueden poner todas las máscaras y datos que necesiten para el ejercicio
  5. %define INDEX_SIZE 2
  6.  
  7. %define POINTER_SIZE 8
  8. %define ITEM_STRENGTH_OFFSET 20
  9. %define ITEM_DURABILITY_OFFSET 24
  10.  
  11. section .text
  12. ; Marca un ejercicio como aún no completado (esto hace que no corran sus tests)
  13. FALSE EQU 0
  14. ; Marca un ejercicio como hecho
  15. TRUE  EQU 1
  16.  
  17. ; Marca el ejercicio 1A como hecho (`true`) o pendiente (`false`).
  18. ;
  19. ; Funciones a implementar:
  20. ;   - es_indice_ordenado
  21. global EJERCICIO_1A_HECHO
  22. EJERCICIO_1A_HECHO: db TRUE ; Cambiar por `TRUE` para correr los tests.
  23.  
  24. ; Marca el ejercicio 1B como hecho (`true`) o pendiente (`false`).
  25. ;
  26. ; Funciones a implementar:
  27. ;   - indice_a_inventario
  28. global EJERCICIO_1B_HECHO
  29. EJERCICIO_1B_HECHO: db TRUE ; Cambiar por `TRUE` para correr los tests.
  30.  
  31. ;; La funcion debe verificar si una vista del inventario está correctamente
  32. ;; ordenada de acuerdo a un criterio (comparador)
  33.  
  34. ;; bool es_indice_ordenado(item_t** inventario, uint16_t* indice, uint16_t tamanio, comparador_t comparador);
  35.  
  36. ;; Dónde:
  37. ;; - `inventario`: Un array de punteros a ítems que representa el inventario a
  38. ;;   procesar.
  39. ;; - `indice`: El arreglo de índices en el inventario que representa la vista.
  40. ;; - `tamanio`: El tamaño del inventario (y de la vista).
  41. ;; - `comparador`: La función de comparación que a utilizar para verificar el
  42. ;;   orden.
  43. ;;
  44. ;; Tenga en consideración:
  45. ;; - `tamanio` es un valor de 16 bits. La parte alta del registro en dónde viene
  46. ;;   como parámetro podría tener basura.
  47. ;; - `comparador` es una dirección de memoria a la que se debe saltar (vía `jmp` o
  48. ;;   `call`) para comenzar la ejecución de la subrutina en cuestión.
  49. ;; - Los tamaños de los arrays `inventario` e `indice` son ambos `tamanio`.
  50. ;; - `false` es el valor `0` y `true` es todo valor distinto de `0`.
  51. ;; - Importa que los ítems estén ordenados según el comparador. No hay necesidad
  52. ;;   de verificar que el orden sea estable.
  53.  
  54. global es_indice_ordenado
  55. es_indice_ordenado:
  56.     ; Prologo (uso volátiles porque vamos a llamar funciones externas en varias iteraciones.)
  57.     push rbp
  58.     mov  rbp, rsp
  59.     sub  rsp, 16 ; Solo uso 8, pero los otros 8 son para mantenerse alineados, ya que uso 4 registros volatiles
  60.     push r15
  61.     push r14
  62.     push r13
  63.     push r12
  64.  
  65.     mov r15, rdi     ; R15 = inventario
  66.     mov r14, rsi     ; R14 = indice
  67.     mov r13, rdx     ; R13 = tamaño
  68.     dec r13          ; Decremento R13 porque queremos interar Tamaño - 1 veces
  69.     xor r12, r12     ; R12 = contador
  70.     mov [rbp-8], rcx ; RBP-8, comparador
  71.    
  72.     .loop:
  73.         cmp r12, r13 ; Reviso si el contador y el tamaño-1 son iguales
  74.         je .en_true  ; Si lo son, termino en true, ya que todos los elementos fueron revisados
  75.        
  76.         xor rdx, rdx ; Vacío rdx y r8 por si tienen basura
  77.         xor r8, r8  
  78.  
  79.         mov dx,  word [r14]     ; Cargo el indice en dx
  80.         mov r8w, word [r14 + 2] ; Cargo el proximo indice en r8w, para comparar
  81.         mov rdi, [r15 + rdx*POINTER_SIZE] ; En rdi, cargo el item del inventario en el indice de cx
  82.         mov rsi, [r15 + r8*POINTER_SIZE]  ; En rsi, cargo el item del inventario que le sigue en la jerarquía
  83.  
  84.         call [rbp-8] ; Llamo al comparador, solo se que en rax me queda un 1 o un 0.
  85.  
  86.         cmp ax, 0    ; Si ax es 0, la comparación no fue esperada, entonces el indice no está ordenado
  87.         je .en_false ; Entonces terminamos en false
  88.        
  89.         ; Caso contrario, continuo iterando.
  90.         add r14, INDEX_SIZE ; +2 a r14, así vemos el próximo indice.
  91.         inc r12             ; +1 al contador
  92.         jmp .loop           ; Seguimos iterando
  93.  
  94.     .en_false:
  95.         mov rax, 0 ; Pongo 0 (false en rax) y termino
  96.         jmp .fin   ; Uso jmp para saltearme la próxima label (en_true)
  97.  
  98.     .en_true:
  99.         mov rax, 1 ; Pongo 1 (true) en rax y termino
  100.  
  101.     .fin:
  102.     ; Epilogo
  103.     pop r12
  104.     pop r13
  105.     pop r14
  106.     pop r15
  107.     add rsp, 16
  108.    
  109.     mov rsp, rbp
  110.     pop rbp
  111.     ret
  112.  
  113. ;; Dado un inventario y una vista, crear un nuevo inventario que mantenga el
  114. ;; orden descrito por la misma.
  115.  
  116. ;; La memoria a solicitar para el nuevo inventario debe poder ser liberada
  117. ;; utilizando `free(ptr)`.
  118.  
  119. ;; item_t** indice_a_inventario(item_t** inventario, uint16_t* indice, uint16_t tamanio);
  120.  
  121. ;; Donde:
  122. ;; - `inventario` un array de punteros a ítems que representa el inventario a
  123. ;;   procesar.
  124. ;; - `indice` es el arreglo de índices en el inventario que representa la vista
  125. ;;   que vamos a usar para reorganizar el inventario.
  126. ;; - `tamanio` es el tamaño del inventario.
  127. ;;
  128. ;; Tenga en consideración:
  129. ;; - Tanto los elementos de `inventario` como los del resultado son punteros a
  130. ;;   `ítems`. Se pide *copiar* estos punteros, **no se deben crear ni clonar
  131. ;;   ítems**
  132.  
  133. global indice_a_inventario
  134. indice_a_inventario:
  135.  
  136.     ; Prologo
  137.     push rbp
  138.     mov  rbp, rsp
  139.     sub  rsp, 16 ; Solo uso 8, pero los otros 8 son para mantenerse alineados, ya que uso 4 registros volatiles
  140.     push r15
  141.     push r14
  142.     push r13
  143.     push r12
  144.  
  145.     mov r15, rdi ; Muevo el inventario a r15
  146.     mov r14, rsi ; Muevo el indice a r14
  147.     mov r13, rdx ; Muevo el tamaño a r13
  148.     xor r12, r12 ; Creo un contador en r12
  149.  
  150.  
  151.     mov  rdi, POINTER_SIZE ; Me traigo el tamaño de puntero a rdi
  152.     imul rdi, r13          ; y lo multiplico por el tamaño para ver cuanta memoria alocar
  153.     call malloc            ; Dejo en rax un item_t** nuevo, para devolver
  154.     mov [rbp-8], rax       ; Guardo en stack el puntero, ya que voy a incrementar rax
  155.  
  156.  
  157.     .loop:
  158.         cmp r12, r13 ; Comparo mi contador con mi tamaño.
  159.         je .end      ; Si son iguales, terminamos de armar nuestro inventario
  160.        
  161.         xor rdx,rdx         ; Vacío rdx en caso de que tenga basura
  162.         mov dx, word [r14]  ; Cargo el indice en dx
  163.         mov rdi,[r15 + rdx*POINTER_SIZE] ; Busco inventario[indice] con indice en dx
  164.         mov [rax], rdi      ; Muevo el puntero a rax para posicionarlo en la lista
  165.  
  166.  
  167.         inc r12               ; +1 al contador
  168.         add rax, POINTER_SIZE ; +8 a rax, para poder agregar el proximo puntero
  169.         add r14, INDEX_SIZE   ; +2 a r14, así vemos el próximo indice.
  170.         jmp .loop
  171.  
  172.  
  173.     .end:
  174.         ; Muevo nuestro puntero guardado a rax
  175.         mov rax, [rbp-8]
  176.  
  177.         ; Epílogo
  178.         pop r12
  179.         pop r13
  180.         pop r14
  181.         pop r15
  182.         add rsp, 16
  183.         mov rsp, rbp
  184.         pop rbp
  185.         ret
  186.  
  187.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement