default rel global _blur_asm global blur_asm extern convulcion_matriz ; Alias para no volverme loco con los registros %define src rdi %define dst rsi %define cols rdx %define filas r14 %define sigma xmm0 %define radius r8 %define cont_c r9 %define matriz r10 %define filas_faltan r11 %define col_faltan r12 %define basura r13 ; Algunos defines ultiles %define PIXEL_SIZE 4 ; Mascaras y esas cosas section .data section .text ;void blur_asm ( ;unsigned char *src, ;unsigned char *dst, ;int filas, ;int cols, ;float sigma, ;int radius) _blur_asm: blur_asm: push rbp mov rbp, rsp ; Stack frame push r9 push r10 push r11 push r12 push r13 push r14 push r15 .init: mov r14,rcx ;guardo rcx para loop mov r9, rdx ;salvo rdx por los mul mov rax, PIXEL_SIZE mul cols mul radius ; rax:=cols*pix_size*radius => cuantas filas debo saltear ;add src, rax add dst, rax ; Avanzo "radius" filas (col*pix_size*radius) sub filas, radius ;acomodo filas para ignorar los bordes sub filas, radius ;acomodo filas para ignorar los bordes mov cols, r9 ;recupero cols por el mul sub cols, radius ;resto radius columnas sub cols, radius ;resto radius columnas mov rax, PIXEL_SIZE mul cols mov cols, rax ;cols:=cols*pix_size .iniciarFila: ;lea src, [src+PIXEL_SIZE*radius] ;avanzo radius pixeles (borde) lea dst, [dst+PIXEL_SIZE*radius] ;avanzo radius pixeles (borde) xor cont_c,cont_c .loop: cmp cols, cont_c ; Comparo tamaƱo con el contador je .finFila ; Si ya recorri la imagen voy al final mov filas_faltan, radius;FIXME este radius es pixeles no bytes add filas_faltan, radius add filas_faltan, PIXEL_SIZE ; 2r+1 filas .loopInterno: mov col_faltan, radius add col_faltan, radius add col_faltan, PIXEL_SIZE ; 2r+1 columnas .loopFila: ;faltan <4? me muevo para atras 4-faltantes pix ;levanto 4px movdqu xmm2, [src] ; Cargo 4 pix de la imagen 1 => xmm0 = |B(P1)|G(P1)|R(P1)|A(P1)|B(P2)|G(P2)|......| mov basura, 4 sub basura, col_faltan mov rax, PIXEL_SIZE mul basura;rdx? ;shift (4-faltantes) bytes psrldq xmm2, basura ;ok, borre los que no queria ;desempaqueto cada pixel a un registro (cada elem como dword) punpcklbw xmm2, xmm3 punpckhbw xmm2, xmm4 punpcklwd xmm3, xmm5 punpckhwd xmm3, xmm6 punpcklwd xmm4, xmm7 punpckhwd xmm4, xmm8 ;cargo 1 elem de matriz como single ;FIXME esto carga 4 movdqu xmm9, [matriz] ;lo clono con mascara a los 4 elem del xmm ;multiplico cada pixel por su coeficiente de la matriz(float) mulps xmm5, xmm9 mulps xmm6, xmm9 mulps xmm7, xmm9 mulps xmm8, xmm9 ;acumulo addps xmm10, xmm5 addps xmm10, xmm6 addps xmm10, xmm7 addps xmm10, xmm8 ;actualizo cuantos faltan sub col_faltan, 4*PIXEL_SIZE cmp col_faltan, 4 jg .loopFila cmp col_faltan, 0 jle .finFilaInterna ;me faltan entre 0 y 4 pixeles, retrocedo suficiente para que me falten 4 exactos lea src, [src-(4-col_faltan)] jmp .loopFila .finFilaInterna: dec filas_faltan cmp filas_faltan, 0 je .sumar jmp .loopInterno ;avanzo ancho img - (2k+1 pix) ;faltan >0 filas? jmp .loopInterno .sumar: .write: movdqu [dst], xmm10 ; Escribo en el destino .endLoop: add src, PIXEL_SIZE ; Incremento 4 pixeles add dst, PIXEL_SIZE add cont_c, PIXEL_SIZE jmp .loop .finFila: dec filas cmp filas, qword 0 je .fin lea src, [src+PIXEL_SIZE*radius] ;agrego radius a la columna (termino la fila) lea dst, [dst+PIXEL_SIZE*radius] jmp .iniciarFila .fin: pop r15 pop r14 pop r13 pop r12 pop r11 pop r10 pop r9 pop rbp ret