-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathlista_asm.asm
600 lines (495 loc) · 11.8 KB
/
lista_asm.asm
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
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
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
extern fprintf
extern malloc
extern free
extern fopen
extern fclose
extern insertarAtras
; PALABRA
global palabraLongitud
global palabraMenor
global palabraFormatear
global palabraImprimir
global palabraCopiar
; LISTA y NODO
global nodoCrear
global nodoBorrar
global oracionCrear
global oracionBorrar
global oracionImprimir
; AVANZADAS
global longitudMedia
global insertarOrdenado
global filtrarPalabra
global descifrarMensajeDiabolico
; YA IMPLEMENTADAS EN C
extern palabraIgual
extern insertarAtras
; /** DEFINES **/ >> SE RECOMIENDA COMPLETAR LOS DEFINES CON LOS VALORES CORRECTOS
%define NULL 0
%define TRUE 1
%define FALSE 0
%define LISTA_SIZE 8
%define OFFSET_PRIMERO 0
%define NODO_SIZE 16
%define OFFSET_SIGUIENTE 0
%define OFFSET_PALABRA 8
section .rodata
section .data
new_line: db 10, 0
append_file: db 'a', 0
empty: db '<oracionVacia>', 10, 0
emptyDiabolico db '<sinMensajeDiabolico>', 10, 0
section .text
;/** FUNCIONES DE PALABRAS **/
;-----------------------------------------------------------
; unsigned char palabraLongitud( char *p );
palabraLongitud:
; RDI puntero a la palabra
xor r8, r8 ; index
xor r9, r9
cPalabraLongitud:
mov r9b, [rdi + r8]
inc r8
cmp r9b, NULL ; 0 es fin de string
jnz cPalabraLongitud
sub r8, 1 ; resto 1 para que no cuente el fin de string
mov rax, r8
ret
; bool palabraMenor( char *p1, char *p2 );
palabraMenor:
; RDI primer puntero a la primer palabra
; RSI segundo puntero a la segunda palabra
xor r10, r10
xor r11, r11
xor r8, r8 ; index
cPalabraMenor:
mov r10b, [rdi + r8]
mov r11b, [rsi + r8]
inc r8
; si alguna palabra llego a su fin salto
cmp r10b, NULL
jz finalPalabra
cmp r11b, NULL
jz finalPalabra
cmp r10b, r11b
jz cPalabraMenor
jl esMenor
; si no es menor, ni igual, entonces debe ser mayor
jmp esMayor
finalPalabra:
cmp r10b, r11b
jge esMayor
esMenor:
mov rax, TRUE
ret
esMayor:
mov rax, FALSE
ret
; void palabraFormatear( char *p, void (*funcModificarString)(char*) );
palabraFormatear:
lea r8, [rsi]
sub rsp, 8
call r8
add rsp, 8
ret
; void palabraImprimir( char *p, FILE *file );
palabraImprimir:
; escribo palabra
xchg rdi, rsi
push rdi
call fprintf
pop rdi
;escribo new line
sub rsp, 8
mov rsi, new_line
call fprintf
add rsp, 8
ret
; char *palabraCopiar( char *p );
palabraCopiar:
; rdi palabra a copiar
xor r8, r8 ; contador
xor r9, r9 ; copia de palabra
xor r10, r10 ; letra actual
xor r11, r11 ; tamaño palabra
; obtengo tamaño de palabra para saber
; cuanto debo reservar
sub rsp, 8
call palabraLongitud
add rsp, 8
mov r11, rax
add r11, 1 ; sumo el final de string
; reservo memoria para la copia
push rdi
mov rdi, r11
call malloc
pop rdi
mov r9, rax
cPalabraCopiar:
; copio letra por letra
mov r10b, [rdi + r8]
mov [r9 + r8], r10b
inc r8
cmp r10b, 0
jnz cPalabraCopiar
mov rax, r9
ret
;/** FUNCIONES DE LISTA Y NODO **/
;-----------------------------------------------------------
; nodo *nodoCrear( char *palabra );
nodoCrear:
; reservo memoria para el nodo
push rdi
mov rdi, NODO_SIZE
call malloc
pop rdi
lea r11, [rdi]
mov [rax + OFFSET_PALABRA], r11
mov qword [rax + OFFSET_SIGUIENTE], NULL
; rax ya tiene el puntero ;)
ret
; void nodoBorrar( nodo *n );
nodoBorrar:
; primero libero la palabra
; obtengo direccion de memoria al puntero de la palabra
mov r8, [rdi + OFFSET_PALABRA]
push rdi
mov rdi, r8
call free
pop rdi
; rdi ya tiene el puntero al nodo
sub rsp, 8
call free
add rsp, 8
ret
; lista *oracionCrear( void );
oracionCrear:
; reservo memoria para la lista
mov rdi, LISTA_SIZE
sub rsp, 8
call malloc
add rsp, 8
mov qword [rax + OFFSET_PRIMERO], NULL
; rax ya tiene el puntero ;)
ret
; void oracionBorrar( lista *l );
; %define NODO_SIZE 16
; %define OFFSET_SIGUIENTE 0
; %define OFFSET_PALABRA 8
oracionBorrar:
; puntero al primer nodo
mov r8, [rdi + OFFSET_PRIMERO]
cOracionBorrar:
cmp r8, NULL
jnz liberarNodo
jmp liberarLista
liberarNodo:
mov r9, [r8 + OFFSET_SIGUIENTE] ; puntero al siguiente
push rdi
push r9
sub rsp, 8
mov rdi, r8 ; puntero que quiero liberar
call nodoBorrar
add rsp, 8
pop r9
pop rdi
mov r8, r9
jmp cOracionBorrar
liberarLista:
; rdi posee la direccion de mem a la lista
sub rsp, 8
call free
add rsp, 8
ret
; void oracionImprimir( lista *l, char *archivo, void (*funcImprimirPalabra)(char*,FILE*) );
oracionImprimir:
push rdi
push rsi
push rdx
mov rdi, rsi
mov rsi, append_file
call fopen
pop rdx
pop rsi
pop rdi
mov r8, rax ; puntero al archivo :D
mov r9, [rdi + OFFSET_PRIMERO]
cmp r9, NULL
jz listaVacia
cOracionImprimir:
cmp r9, NULL
jnz imprimeNodo
jmp finOracionImprimir
imprimeNodo:
mov r10, [r9 + OFFSET_PALABRA]
push rdi
push rsi
push r9
push r8
push rdx
push rax
sub rsp, 8
mov rdi, r10
mov rsi, r8
call rdx
add rsp, 8
pop rax
pop rdx
pop r8
pop r9
pop rsi
pop rdi
mov r9, [r9 + OFFSET_SIGUIENTE]
jmp cOracionImprimir
listaVacia:
mov rdi, empty
mov rsi, r8
push rdi
push rax
sub rsp, 8
call rdx
add rsp, 8
pop rax
pop rdi
finOracionImprimir:
mov rdi, rax
sub rsp, 8
call fclose
add rsp, 8
ret
;/** FUNCIONES AVANZADAS **/
;-----------------------------------------------------------
; float longitudMedia( lista *l );
longitudMedia:
; RDI lista
push r12 ; contador de nodos
push r13 ; sumador longitues
push r14 ; puntero a nodo
xor r12, r12
xor r13, r13
mov r14, [rdi + OFFSET_PRIMERO]
cLongitudMedia:
cmp r14, NULL
jnz procesarLongitudNodoYContar
jmp calculaLongitudMedia
procesarLongitudNodoYContar:
inc r12
mov rdi, [r14 + OFFSET_PALABRA]
call palabraLongitud
add r13, rax
mov r14, [r14 + OFFSET_SIGUIENTE]
jmp cLongitudMedia
calculaLongitudMedia:
; calcular promedio y devolver
cmp r12, 0
jz finLongitudMedia
movq xmm0, r13
movq xmm1, r12
divss xmm0, xmm1
finLongitudMedia:
pop r14
pop r13
pop r12
ret
; void insertarOrdenado( lista *l, char *palabra, bool (*funcCompararPalabra)(char*,char*) );
insertarOrdenado:
; RDI puntero a la lista
; RSI puntero a la palabra a insertar
; RDX puntero a la función de comparación
push r12 ; puntero al nodo actual
push r13
push r14
mov r12, [rdi + OFFSET_PRIMERO]
cmp r12, NULL
jnz crearNuevoNodo
; si la lista esta vacía simplemente inserto y chau
call insertarAtras
jmp finInsertarOrdenado
crearNuevoNodo:
push rdi
push rdx
push rsi
sub rsp, 8
mov rdi, rsi
call nodoCrear
add rsp, 8
pop rsi
pop rdx
pop rdi
mov r13, rax ; puntero al nuevo nodo
push rdi
push rdx
push rsi
; si debe insertar antes del primer nodo
mov rdi, [r13 + OFFSET_PALABRA]
mov rsi, [r12 + OFFSET_PALABRA]
sub rsp, 8
call rdx
add rsp, 8
pop rsi
pop rdx
pop rdi
cmp rax, TRUE
jne cInsertarOrdenado
mov [rdi + OFFSET_PRIMERO], r13
mov [r13 + OFFSET_SIGUIENTE], r12
jmp finInsertarOrdenado
cInsertarOrdenado:
mov r14, r12
mov r12, [r12 + OFFSET_SIGUIENTE]
cmp r12, NULL
jnz compararPalabras
jmp insertaOrdenadamente
compararPalabras:
mov rdi, [r13 + OFFSET_PALABRA]
mov rsi, [r12 + OFFSET_PALABRA]
push rdi
push rdx
push rsi
sub rsp, 8
call rdx
add rsp, 8
pop rsi
pop rdx
pop rdi
cmp rax, TRUE
jne cInsertarOrdenado
insertaOrdenadamente:
mov [r13 + OFFSET_SIGUIENTE], r12
mov [r14 + OFFSET_SIGUIENTE], r13
finInsertarOrdenado:
pop r14
pop r13
pop r12
ret
; void filtrarAltaLista( lista *l, bool (*funcCompararPalabra)(char*,char*), char *palabraCmp );
filtrarPalabra:
; RDI puntero a la lista
; RSI puntero a la funcion de comparacion
; RDX puntero a la palabra de comparacion
push r12 ; puntero al nodo actual
push r13 ; guarda el anterior elemento
push r14 ; temporal auxiliar
push r15 ; puntero a la funcion de comparacion (comodidad)
mov r15, rsi
xor r13, r13
mov r12, [rdi + OFFSET_PRIMERO]
cFiltrarPalabra:
cmp r12, NULL
jz finFiltrarPalabra
mov rdi, [r12 + OFFSET_PALABRA]
mov rsi, rdx
push rdi
push rdx
sub rsp, 8
call r15
add rsp, 8
pop rdx
pop rdi
cmp rax, FALSE
jz reapuntarNodos
jmp simplementeIterarFP
reapuntarNodos:
; si no tengo el precedente seteado
; es el principio de la lista
mov r14, [r12 + OFFSET_SIGUIENTE]
cmp r13, NULL
jz reapuntarPrimeroEnLista
jmp reapuntarGenerico
reapuntarPrimeroEnLista:
mov [rdi + OFFSET_PRIMERO], r14
jmp borrarEIterar
reapuntarGenerico:
mov [r13 + OFFSET_SIGUIENTE], r14
borrarEIterar:
mov r14, [r12 + OFFSET_SIGUIENTE]
mov rdi, r12
push rdi
push rdx
sub rsp, 8
call nodoBorrar
add rsp, 8
pop rdx
pop rdi
mov r12, r14
jmp cFiltrarPalabra
simplementeIterarFP:
mov r13, r12
mov r12, [r12 + OFFSET_SIGUIENTE]
jmp cFiltrarPalabra
finFiltrarPalabra:
pop r15
pop r14
pop r13
pop r12
ret
; void descifrarMensajeDiabolico( lista *l, char *archivo, void (*funcImpPbr)(char*,FILE* ) );
descifrarMensajeDiabolico:
push r12 ; puntero a los nodos
push r13 ; puntero al archivo
push r14 ; puntero a la funcion que imprime
push r15 ; contador de paridad
push rbx
push rbp
sub rsp, 8
mov rbp, rsp
mov r13, rsi
mov r14, rdx
xor rax, rax
xor r15, r15
mov r12, [rdi + OFFSET_PRIMERO]
mov rdi, r13
mov rsi, append_file
call fopen
mov r13, rax
; pusheo todos los elementos en el stack
cmp r12, NULL
jnz cDMD
mov rdi, emptyDiabolico
mov rsi, r13
call r14
jmp finDMD
; si esta vacia escribo
cDMD:
mov rcx, [r12 + OFFSET_PALABRA]
push rcx ; pusheo la palabra al stack
inc r15
mov r12, [r12 + OFFSET_SIGUIENTE]
cmp r12, NULL
jnz cDMD
compAndPopDMD:
cmp r15, 0
jz finDMD
; divido para saber cuanto ajustar el stack ;)
mov rax, r15
mov rbx, 2
xor rdx, rdx
div rbx
dec r15
; rdx 0 o 1
cmp rdx, 0
je popAndSub
justPop:
pop rax
mov rdi, rax
mov rsi, r13
call r14
jmp compAndPopDMD
popAndSub:
pop rax
sub rsp, 8
mov rdi, rax
mov rsi, r13
call r14
add rsp, 8
jmp compAndPopDMD
finDMD:
mov rdi, r13
call fclose
add rsp, 8
pop rbp
pop rbx
pop r15
pop r14
pop r13
pop r12