| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- ; asmsyntax=nasm
- default rel
- global _diff_asm
- global diff_asm
- ; Alias para no volverme loco con los registros
- %define src rdi
- %define src2 rsi
- %define dst rdx
- %define cont rcx
- %define size r8
- ; Algunos defines ultiles
- %define PIXEL_SIZE 4
- %define ALPHA_VALUE 255
- %define ALPHA_POS 15
- ; Mascaras y esas cosas
- section .data
- BLUE_MASK: db 0,0,0,ALPHA_POS,4,4,4,ALPHA_POS,8,8,8,ALPHA_POS,12,12,12,ALPHA_POS ; TODO: Ver que hacer con el alpha
- ;TODO: Si el alpha viene en 255 entonces puedo poner el mismo byte que vino!!!!
- GREEN_MASK: db 1,1,1,255,5,5,5,255,9,9,9,255,13,13,13,255
- RED_MASK: db 2,2,2,255,6,6,6,255,10,10,10,255,14,14,14,255
- section .text
- ;void diff_asm (
- ;unsigned char *src, unsigned char *src2, unsigned char *dst, int filas, int cols)
- _diff_asm:
- diff_asm:
- push rbp
- mov rbp, rsp ; Stack frame
- .calc_size: ; Calculo el tamaño de la imagen en bytes
- mov r9, dst ; Muevo el destino un rato para hacer el calculo del tamaño de la imagen
- mov rax, cont ; Cargo filas
- mul size ; Multiplico por las columnas
- xor dst, dst ; Limpio temportal
- mov dst, PIXEL_SIZE ; Multiplico temporal
- mul dst ; Multiplico por el tamaño del pixel
- mov size, rax ; Guardo el tamaño
- mov dst, r9
- xor cont, cont ; Limpio el contador
- .pre_loop:
- xor rax, rax
- mov al, ALPHA_VALUE ; Cargo el valor de alfa
- pxor xmm11, xmm11 ; Limpio xmm11
- movq xmm11, rax ; Cargo el byte en rax
- pslldq xmm11, ALPHA_POS ; Lo muevo en la posición del ultimo alpha
- pxor xmm15, xmm15 ; Lo uso como 0 para desempaquetar
- movdqu xmm14, [BLUE_MASK] ; Cargo la mascara para sacar el componente azul de cada pixel y calcular el maximo con otros comp
- movdqu xmm13, [GREEN_MASK] ; Simil anterior pero con verde
- movdqu xmm12, [RED_MASK]
- .loop:
- cmp cont, size ; Comparo tamaño con el contador
- jge .fin ; Si ya recorri la imagen voy al final
- pxor xmm1, xmm1
- movdqu xmm0, [src] ; Cargo la imagen 1 => xmm0 = |B(P1)|G(P1)|R(P1)|A(P1)|B(P2)|G(P2)|......|
- movdqu xmm2, [src2] ; Cargo la imagen 2 => xmm1 = |B(P1)|G(P1)|R(P1)|A(P1)|B(P2)|G(P2)|......|
- .cuentas: ; Resto componente a componente de 4 pixeles de cada imagen
- movdqu xmm1, xmm0 ; Copia para desempaquetar
- punpcklbw xmm0, xmm15 ; Desempaqueto la parte baja de imagen 1
- punpckhbw xmm1, xmm15 ; Desempaqueto parte alta de imagen 1
- movdqu xmm3, xmm2 ; Copia para desempaquetar
- punpcklbw xmm2, xmm15 ; Desempaqueto aprte baja de imagen 1
- punpckhbw xmm3, xmm15 ; Parte alta de imagen 1
- psubw xmm2, xmm0 ; Resto parte baja de cada imagen
- psubw xmm3, xmm1 ; xmm3 = |B(img1_P1) - R(img2_P1)|G(Img1_P1) - Img2_P2|....|
- pabsw xmm0, xmm2 ; Calculo el valor absoluto de la resta anterior
- pabsw xmm1, xmm3
- packuswb xmm0, xmm1 ; Empaqueto los valores de nuevo
- .max:
- paddb xmm0, xmm11 ; Sumo el canal alpha solitario en xmm0
- movdqu xmm2, xmm0 ; Copias para usar los shuffle
- movdqu xmm3, xmm0
- pshufb xmm0, xmm14 ; Pongo en cada byte de cada pixel el componente azul
- pshufb xmm2, xmm13 ; Simil anterior, con verde
- pshufb xmm3, xmm12 ; Rojo
- pmaxub xmm2, xmm3 ; Calculo el mayor de los componentes verde y rojo
- pmaxub xmm0, xmm2 ; Calculo el mayor de los componentes de la comparación anterior y azul
- .write:
- movdqu [dst], xmm0 ; Escribo en el destino
- .endLoop:
- add src, PIXEL_SIZE * 4 ; Incremento 4 pixeles
- add src2, PIXEL_SIZE * 4
- add dst, PIXEL_SIZE * 4
- add cont, PIXEL_SIZE * 4
- jmp .loop
- .fin:
- pop rbp
- ret
|