or r30, r0, 0x0000F000; Iniciamos el puntero de pila a la posicion 0x0000F000 ;-----------------------------------MACROS--------------------------------------- PUSH:MACRO(ra) subu r30,r30,4 st ra,r30,0 ENDMACRO POP:MACRO(ra) ld ra,r30,0 addu r30,r30,4 ENDMACRO LEA:MACRO (reg, ETIQ) or reg, r0, low(ETIQ) or.u reg, reg, high(ETIQ) ENDMACRO ;Carga el registro ra con la dirección efectiva definida por la etiqueta eti. DBNZ:MACRO (reg, ETIQ) sub reg, reg, 1 cmp r4, reg, r0 bb0 eq, r4, ETIQ ENDMACRO ;Decrementa el registro ra y salta a la etiqueta eti si no es cero el resultado ;utilizando r5 como registro auxiliar. org 200 imagen: data 4 data 8 data 0xFF00FF00 data 0x00FF00FF data 0xFF00FF00 data 0x00FF00FF data 0xFF00FF00 data 0x00FF00FF data 0xFF00FF00 data 0x00FF00FF MFiltro: data 8 data 0 data 1 Test:add r30, r30, 20000 LEA(r22, imagen) LEA(r23, MFiltro) add r24, r0, 2; NCambios add r25, r0, 0; NFiltrados PUSH(r25) PUSH(r24) PUSH(r23) PUSH(r22) bsr FiltRec stop; ;---------------------------------FILTRO_REC------------------------------------- FiltRec:PUSH(r1); Guardamos dirección de retorno PUSH(r31); Guardamos el FP del llamante addu r31, r30, r0; Activamos el marco de pila ld r2, r31, 8; r2: Dirección imagen ld r3, r31, 12; r3: Direccion MFiltro ld r4, r2, 0; r4: M Filas ld r5, r2, 4; r5: N Columnas mulu r8, r4, r5; r8: Numero de elementos de la imagen ajustar:subu r8, r8, 4; Restamos 4 al total de elementos cmp r28, r8, 4; Comparamos los elementos restantes con 4 bb1 ge, r28, ajustar; Si es mayor o igual que 4 volvemos a ajustar mulu r4, r4, r5; Ponemos en r4 el total de elementos addu r4, r4, 8; Añadimos espacio al total de lementos para M y N cmp r28, r8, 0; Comparamos los elementos restantes con 0 bb1 eq, r28, reservar; addu r4, r4, r8; Ajustamos por exceso el total de elementos reservar:subu r30, r30, r4; Reservamos el espacio necesario para a imagen filtrada addu r5, r30, 0; Metemos en r5 la direccion de Imagen filtrada PUSH(r3); Pasamos Parametro Mfiltro PUSH(r5); Pasamos Parametro Imagen Filtrada PUSH(r2); Pasamos Parametro Imagen bsr Filtro; POP(r2) POP(r5) POP(r3) ld r26, r31, 20; r26: NFiltrados addu r26, r26, 1; cmp r28, r26, 15; Comparamos NFiltrados con 15 que es el maximo de pasadas bb1 eq, r28, finr; PUSH(r3); Guardamos MFiltro PUSH(r5); Pasamos Parametro Imagen Filtrada PUSH(r2); Pasamos Parametro Imagen bsr Comp; POP(r2) POP(r5) POP(r3) ld r27, r31, 16; r27: NCambios cmp r28, r29, r27; Comparamos las diferencias de las imagenes con NCambios bb1 lt, r28, finr; Si el valor devuelto es menor que NCambios saltamos a finr PUSH(r26); Pasamos Parametro NFiltrados PUSH(r27); Pasamos Parametro NCambios PUSH(r3); Pasamos Parametro Mfiltro PUSH(r5); Pasamos Parametro Imagen Filtrada bsr FiltRec; finr:or r29, r26, r26; Metemos NFiltrados de valor de retorno addu r9, r30, 0; r9: Direccion Imagen Filtrada ld r10, r31, 8; r10: Direccion imagen original ld r11, r9, 0; r11: Mfilas ld r12, r9, 4; r12: Ncolumnas mulu r11, r11, r12; r11: Numero de elementos de la matriz addu r9, r9, 8; Ponemos r9 apuntando al primer pixel de imagen filtrada addu r10, r10, 8; Ponemos r10 apuntando al primer pixel de imagen original copiar:ld.bu r13, r9, 0; r13: Pixel filtrado a copiar en imagen original st.b r13, r10, 0; Copiamos el pixel en imagen original subu r11, r11, 1; Restamos 1 al numero de elementos addu r9, r9, 1; Apuntamos al siguiente elemento de imagen filtrada addu r10, r10, 1; Apuntamos al siguiente elemento de imagen Original cmp r28, r11, 0; Comparamos los elementos restantes con 0 bb1 ne, r28, copiar; Si no es igual a 0 seguimos copiando or r30, r31, r31; Destruimos marco de pila POP(r31); POP(r1); jmp(r1); ;-------------------------------FIN_FILTRO_REC----------------------------------- ;-----------------------------------FILTRO--------------------------------------- Filtro:PUSH(r1); Guardamos dirección de retorno PUSH(r31); Guardamos el FP del llamante addu r31, r30, r0; Activamos el marco de pila ld r19, r31, 8; r19: Direccion Imagen ld r20, r31, 12; r20: Dirección ImagenFiltrada ld r21, r31, 16; r21: Dirección MFiltro ld r22, r19, 0; r22: M filas ld r23, r19, 4; r23: N Columnas st.b r22, r20, 0; Almacenamos Mfilas en ImagenFiltrada addu r20, r20, 4; Apuntamos al elemento NColumnas de Imagen Filtrada st.b r23, r20, 0; Almacenamos NColumnas en ImagenFiltrada addu r20, r20, 4; Apuntamos al primer pixel de Imagen Filtrada addu r24, r0, 0; r24: Contador de filas i addu r25, r0, 0; r25: Contador de columnas j subu r22, r22, 1; r22: Contiene ahora M-1 Filas subu r23, r23, 1; r23: Contiene ahora N-1 Columnas llamadas: PUSH(r21); Pasamos parametro Mfiltro PUSH(r25); Pasamos parametro j PUSH(r24); Pasamos parametro i PUSH(r19); Pasamos parametro Imagen bsr FilPixel POP(r19); POP(r24); POP(r25); POP(r21); st.b r29, r20, 0; Almacenamos el resultado de Filpixel en Imagen Filtrada cmp r28, r25, r23; Comparo si estoy en la ultima columna bb1 eq, r28, masfila; Si es la ultima columna saltamos a masfila addu r20, r20, 1; Corremos el puntero al siguiente pixel de imagen filtrada addu r25, r25, 1; Aumentamos contador de columnas j bsr llamadas; volvemos al bucle masfila: cmp r28, r24, r22; Comparo si estoy en la ultima fila bb1 eq, r28, cierra; Si es la ultima fila saltamos a cierra addu r20, r20, 1; Corremos el puntero al siguiente pixel de imagen filtrada addu r24, r24, 1; Incrementamos el contador de filas i addu r25, r0, 0; Ponemos a 0 el contador de columnas bsr llamadas; Vamos al bucle cierra: POP(r31) POP(r1) jmp(r1) ;---------------------------------FIN_FILTRO------------------------------------- ;---------------------------------FILPIXEL--------------------------------------- FilPixel:PUSH(r1); Guardamos dirección de retorno PUSH(r31); Guardamos el FP del llamante addu r31, r30, r0; Activamos el marco de pila subu r30, r30, 12; añadimos a r30 el espacio en bytes que ocupa la subimagen ld r2, r31, 8; r2: direccion de la imagen ld r3, r31, 12; r3: fila i ld r4, r31, 16; r4: col j ld r5, r31, 20; r5: Mfiltro add r6, r30, 0; r6: Dirección subimagen PUSH(r5); PUSH(r4); Parametro col j PUSH(r3); parametro fila i PUSH(r6); Paramtero direccion subimagen PUSH(r2); Parametro direccion imagen bsr SubMatriz; addu r30, r30, 4; POP(r6) addu r30, r30, 8; PUSH(r6); Pasamos parametro dirección de subimagen bsr ValorPixel; addu r30, r30, 20; Ponemos r30 apuntando a su sitio 12 de la subimagen + 8 de r5 y r6 POP(r31) POP(r1) jmp(r1) ;--------------------------------FIN_FILPIXEL------------------------------------ ;---------------------------------SUBMATRIZ-------------------------------------- SubMatriz:PUSH(r1); Guardamos dirección de retorno PUSH(r31); Guardamos el FP del llamante addu r31, r30, r0; Activamos el marco de pila ld r2, r31, 8; r2: Dirección imagen ld r3, r31, 12; r3: Dirección subimagen ld r4, r31, 16; r4: fila i ld r5, r31, 20; r5: columna j ld r6, r2, 0; r6: M filas ld r7, r2, 4; r7: N columnas subu r8, r6, 1; r8: M-1 filas subu r9, r7, 1; r9: N-1 Columnas addu r10, r0, 0; r10: Contador de fila addu r11, r0, 0; r11: Contador de columna addu r12, r2, 8; r12: Puntero elementos imagen addu r13, r3, 0; r13: Puntero elementos subimagen add r18, r0, 9; r18: contiene ahora el tope de 9 elementos cmp r28, r4, 0; Comparamos que este en la primera fila bb1 eq, r28, borde; Si esta en la primera fila saltamos cmp r28, r4, r8; Comparamos que está en la última fila bb1 eq, r28, borde; Si está en la última fila saltamos cmp r28, r5, 0; Comprobamos si está en la primera columna bb1 eq, r28, borde; Si está en la primera columna saltamos cmp r28, r5, r9; Comprobamos si está en la última columna bb1 eq, r28, borde; Si está en la primera columna saltamos interior: subu r15, r4, 1; r15 contiene ahora i-1 addu r14, r0, 0; r14 contador de elementos subu r16, r5, 1; r16 contiene j-1 bsr enfilar; saltamos a enfilar para encontrar el elemento borde: addu r15, r4, 0; r15 contiene i addu r16, r5, 0; r16 contiene j cmp r28, r10, r15; Compruebo si el contador de fila es la misma que i bb1 eq, r28, fila_enc; enfilar: cmp r28, r10, r15; Compruebo si el contador de fila es la misma que i bb1 eq, r28, fila_enc; si es la fila i-1 vamos a fila encontrada addu r12, r12, r7; r12: apunta ahora al primer elemento de la siguiente fila addu r10, r10, 1; Incrementamos contador de filas cmp r28, r10, r15; Compruebo si el contador de fila es la misma que i bb1 ne, r28, enfilar; fila_enc: cmp r28, r11, r16; Comparamos si el contador de columnas es la misma que j bb1 eq, r28, col_enc; columnar: addu r12, r12, 1; apuntamos al siguiente elemento de la imagen addu r11, r11, 1; Incrementamos el contador de columna cmp r28, r11, r16; Comprobamos si la columna actual es la misma que j bb1 ne, r28, columnar; col_enc: ld.bu r17, r12, 0; r17: Contiene el elemento I(i,j) cmp r28, r4, 0; Comparamos que este en la primera fila bb1 eq, r28, insertarBorde; Si esta en la primera fila saltamos cmp r28, r4, r8; Comparamos que está en la última fila bb1 eq, r28, insertarBorde; Si está en la última fila saltamos cmp r28, r5, 0; Comprobamos si está en la primera columna bb1 eq, r28, insertarBorde; Si está en la primera columna saltamos cmp r28, r5, r9; Comprobamos si está en la última columna bb1 eq, r28, insertarBorde; Si está en la primera columna saltamos insertarInt: st.b r17, r13, 0; Almacenamos el valor I(i,j) en la posicion de la matriz addu r13, r13, 1; Corremos el puntero al siguiente elemento de subimagen addu r14, r14, 1; aumentamos contador de elementos cmp r28, r14, 3; comparamos con 3 bb1 eq, r28, act; si es igual actualizamo cmp r28, r14, 6; Comparamos con 6 bb1 eq, r28, act; si es igual actualizamos addu r16, r16, 1; aumentamos j cmp r28, r14, 9; Comparamos con 9 bb1 ne, r28, enfilar; Si no hemos llegado al final salta a enfilar POP(r31) POP(r1) jmp(r1) act: addu r15, r15, 1; aumentamos i subu r16, r5, 1; r16 contiene j-1 addu r11, r0, 0; Ponemos a 0 el contador de columna addu r10, r0, 0; Ponemos el contador de filas a 0 addu r12, r2, 8; r12: Puntero elementos imagen lo ponemos al primer elemento de la fila que hay que copiar bsr enfilar; insertarBorde: st.b r17, r13, 0; Almacenamos el valor I(i,j) en la posicion de la matriz addu r13, r13, 1; Corremos el puntero al siguiente elemento de subimagen subu r18, r18, 1; Decrementamos el tope de elementos cmp r28, r18, 0; Comprobamos si ya hemos rellenado la matriz entera bb1 ne, r28, insertarBorde; Repetimos bucle si no hemos terminado POP(r31) POP(r1) jmp(r1) ;-------------------------------FIN_SUBMATRIZ------------------------------------ ;----------------------------------VALORPIXEL------------------------------------ ValorPixel:PUSH(r1); Guardamos dirección de retorno PUSH(r31); Guardamos el FP del llamante addu r31, r30, r0; Activamos el marco de pila addu r29, r0, 0; r29: Acumulador ld r2, r31, 12; r2: Direccion del Mfiltro ld r3, r2, 0; r3: Valor constante K PUSH(r3); guardamos en pila K ld r3, r2, 4; r3: Valor C PUSH(r3); Guardamos en pila C ld r3, r2, 8; r3: valor B PUSH(r3); Guardamos en pila B ld r4, r31, 8; r4: Dirección de Subimg addu r5, r0, 4; r5: Ponemos el limite de 4 elementos a recorrer bucle2: ld.bu r2, r4, 0; r2: Cargamos un elemento de la Subimg muls r2, r2, r3; r2: Multiplicamos el elemento por el valor B addu r29, r29, r2; Añadimos el resultado de la multiplicación al acumulador subu r5, r5, 1; Restamos 1 al limite de iteraciones addu r4, r4, 1; Ponemos r4 apuntando al siguiente elemento de la Subimg cmp r28, r5, 0; Si el limite no es 0 vuelve al bucle bb1 ne, r28, bucle2; ld.bu r2, r4, 0; r2: cargamos el elemento central de la Subimg ld r3, r30, 4; r3: Valor C muls r2, r2, r3; Multiplicamos el valor central, con el valor C addu r29, r29, r2; Añadimos el resultado al acumulador addu r5, r0, 4; r5: Ponemos el limite de 4 elementos a recorrer addu r4, r4, 1; Ponemos r4 apuntando al siguiente elemento de la Subimg finbuc:ld.bu r2, r4, 0; r2: Cargamos un elemento de la Subimg ld r3, r30, 0; r3: Valor B muls r2, r2, r3; r2: Multiplicamos el elemento por el valor B addu r29, r29, r2; Añadimos el resultado de la multiplicación al acumulador subu r5, r5, 1; Restamos 1 al limite de iteraciones addu r4, r4, 1; Ponemos r6 apuntando al siguiente elemento de la Subimg cmp r28, r5, 0; Si el limite no es 0 vuelve a finbuc bb1 ne, r28, finbuc; ld r3, r30, 8; r3: Valor K divs r29, r29, r3; Dividimos el acumulador entre k y lo guardamos en el acumulador cmp r28, r29, 0; bb1 lt, r28, cero; Si el acumulador es negativo vamos a 0 cmp r28, r29, 255; bb1 gt, r28, maxval; Si el acumulador es positivo y mayor que 255 vamos a maxval or r30, r31, r31; Destruimos marco de pila POP(r31) POP(r1) jmp(r1) cero:addu r29, r0, 0; Ponemos r29 a 0 or r30, r31, r31; Destruimos marco de pila POP(r31) POP(r1) jmp(r1) maxval:addu r29, r0, 255; Ponemos r29 a 255 or r30, r31, r31; Destruimos marco de pila POP(r31) POP(r1) jmp(r1) ;-------------------------------FIN_VALORPIXEL-----------------------------------