ej1.asm 4.76 KB
Newer Older
Daniel Alejandro Maydana's avatar
Daniel Alejandro Maydana committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
extern malloc

section .rodata
; Acá se pueden poner todas las máscaras y datos que necesiten para el ejercicio

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

;typedef struct {
;    char nombre[18];			//OFFSET 0, tamaño 1*18 + 2 padding
;    uint32_t fuerza;			//OFFSET 20, tamaño 4 + 0 padding
;    uint16_t durabilidad;	   //OFFSET 24, tamaño 2 + 2 padding
;} item_t;					      //TOTAL STRUCT SIZE: 28


ITEM_NOMBRE      equ 0
ITEM_FUERZA      equ 20
ITEM_DURABILIDAD equ 24
ITEM_LENGHT      equ 28

PUNTERO_SIZE     equ 8
uint16_size      equ 2

; Marca el ejercicio 1A como hecho (`true`) o pendiente (`false`).
;
; Funciones a implementar:
;   - es_indice_ordenado
global EJERCICIO_1A_HECHO
EJERCICIO_1A_HECHO: db FALSE ; 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 FALSE ; 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:
	; Te recomendamos llenar una tablita acá con cada parámetro y su
	; ubicación según la convención de llamada. Prestá atención a qué
	; valores son de 64 bits y qué valores son de 32 bits o 8 bits.
	;
	; rsi = item_t**     inventario
	; rdi = uint16_t*    indice
	; rdx = uint16_t     tamanio
	; rcx = comparador_t comparador

	push rbp
	mov rbp, rsp
	push r8
	push r10
	push r11
	push r12
Daniel Alejandro Maydana's avatar
Daniel Alejandro Maydana committed
81 82 83 84 85 86
	push r13
	push r14

	
	mov r13, rsi
	mov r14, rdi
Daniel Alejandro Maydana's avatar
Daniel Alejandro Maydana committed
87 88 89 90 91 92 93 94

	mov r8, 1 ; j = 0
	mov rax,1 ; res = true

	.while:
		cmp r8, rdx
		je .end

Daniel Alejandro Maydana's avatar
Daniel Alejandro Maydana committed
95
		; indice[j-1],  indice[j]
Daniel Alejandro Maydana's avatar
Daniel Alejandro Maydana committed
96 97 98
		mov r10,  [rdi + r8      * uint16_size]
		mov r11,  [rdi + r8 - 1  * uint16_size]

Daniel Alejandro Maydana's avatar
Daniel Alejandro Maydana committed
99
		; inventario[indice[j-1]], inventario[indice[j]]
Daniel Alejandro Maydana's avatar
Daniel Alejandro Maydana committed
100
		mov rsi,  [rsi + r10 * PUNTERO_SIZE]
Daniel Alejandro Maydana's avatar
Daniel Alejandro Maydana committed
101
		mov rdi,  [rsi + r11 * PUNTERO_SIZE]
Daniel Alejandro Maydana's avatar
Daniel Alejandro Maydana committed
102 103 104
		call rcx
		cmp rax, 0
		je .end
Daniel Alejandro Maydana's avatar
Daniel Alejandro Maydana committed
105 106 107 108 109 110

		; restaura rdi, rsi
		mov rsi, r13
		mov rdi, r14 

		;incrementa j
Daniel Alejandro Maydana's avatar
Daniel Alejandro Maydana committed
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
		inc r8
		jmp .while
	.end:

	pop r12
	pop r11
	pop r10
	pop r11
	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:
	; Te recomendamos llenar una tablita acá con cada parámetro y su
	; ubicación según la convención de llamada. Prestá atención a qué
	; valores son de 64 bits y qué valores son de 32 bits o 8 bits.
	;
	; rsi = item_t**  inventario
	; rdi = uint16_t* indice
	; rdx = uint16_t  tamanio

	push rbp
	mov rbp, rsp

	sub rsp, 16
	mov [rbp-8], rdx

	push r10
	push r11
	
	mov rax, ITEM_LENGHT
	mul rdx
	mov rsi, rax
	call malloc
	
	mov rcx, 0 ; rcx = i
	.while:
		cmp rcx, [rbp-8]
		je .end
		; indice[i]
		mov r10,  [rdi + rcx * uint16_size]
		; inventario[indice[i]]
		mov r11,  [rsi + r10 * PUNTERO_SIZE]
		; res[i]
		mov [rax + rcx * PUNTERO_SIZE],  r11
		; i++
		inc rcx
		jmp .while

	.end:

	pop r11
	pop r10

	mov rsp, rbp
	pop rbp
	ret

	ret