LEA: MACRO (reg, ETIQ) or reg, r0, low(ETIQ) or.u reg, reg, high(ETIQ) ENDMACRO LOAD: MACRO (reg, ETIQ) LEA(reg, ETIQ) ld reg, reg, 0 ENDMACRO PUSH: MACRO (reg) subu r30, r30, 4 st reg, r30, r0 ENDMACRO POP: MACRO (reg) ld reg, r30, r0 addu r30, r30, 4 ENDMACRO ;Para cargar direcciones de memoria(cadenas) LEA ;Para cargar números LOAD org 1000 ;cadena: data "Prueba\0" ;r29 = 6 cadena: data "ABCDE\0AA" ;C: data "*\0" ;ref: data "*2345*78*0\0" ;from: data 2 ;to: data 12 ;C: data "f\0" ;ref: data "*2345*f78*0\0" ;from: data 2 ;to: data 12 ;C: data "f\0" ;ref: data "*2345*78*0\0" ;from: data 2 ;to: data 12 C: data "7\0" ;ref: data "780789123789\0" from: data 1 to: data 9 ;cadena1: data "1234567890\0" ;cadena2: data "0123456789\0" ;cadena1: data "1234567890\0" ;cadena2: data "1234567089\0" ;cadena1: data "1234567890\0" ;cadena2: data "1234567890\0" ;cadena1: data "12*3456789012*3456789012*3456789012*3456789012*3456789012*34567890\0" ;cadena2: data "12*3456789012*3456789012*345678901*3456789012*3456789012*34567890\0" cadena1: data "789123789\0" cadena2: data "789\0" ;org 21000 ;ref: data "tres tristes tigres comen trigo en un trigal, el primer tigre que...\0" ;max: data 26 ;ref: data "7890123789\0" ;max: data 7 ;ref: data "0789123789\0" ;max: data 7 ;ref: data "780789123789\0" ;max: data 9 ;ref: data "Hola que t?\0" ;max: data 5 ;ref: data "83921034523582\0" ;max: data 12 ;ref: data "83821034523582\0" ;max: data 12 ;ref: data "838210345235825893740902756732298457234902174\0" ;max: data 43 ;ref: data "aaaaaeraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\0" ;max: data 10 ref: data "aaaaaeraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\0" max: data 10 org 20000 jj: data 0 ;ref: data "012378978927892\0" ;max: data 11 ;texto: data "ABCDE\0" ;texto: data "ABCDE\0AA" ;texto: data "ABCDEF4243A85493F839\0" ;texto: data "A\0" ;texto: data "AB\0" ;texto: data "ABC\0" ;texto: data "ABCD\0" ;texto: data "ABCDEF\0" ;texto: data "ABCDEF42\0" ;texto: data "SOL\0A" texto: data "ABCDEF424FA85F9FF8F9FFF\0" ;--------------------------------------------------------------------------------------------------------------------------------- Main_LongCad: LEA (r30,0x0000F000) LEA (r8, cadena) ;guarda en r8 la cadena PUSH (r8) ;carga en la pila r8 bsr LongCad ;saltar al código de LongCad (salto con retorno, para llamar a una subrutina) addu r30, r30, 4 ;ya que la cadena ocupa 4 bytes stop Main_BuscaCar: LEA (r30, 0x0000F000) LOAD (r8, C) ;guarda en r8 C LEA (r9, ref) ;guarda en r9 ref LOAD (r10, from) ;guarda en r10 from LOAD (r11, to) ;guarda en r11 to PUSH (r11) PUSH (r10) PUSH (r9) PUSH (r8) bsr BuscaCar ;saltar al código de BuscaCar addu r30, r30, 16 stop Main_CoincidenCad: LEA (r30, 0x0000F000) LEA (r8, cadena1) ;guarda en r8 cadena1 LEA (r9, cadena2) ;guarda en r9 cadena2 PUSH (r9) PUSH (r8) bsr CoincidenCad ;saltar al código CoincidenCad addu r30, r30, 8 stop Main_BuscaMax: ;LEA (r30, 0x0000F000) ;add r2, r0, 2000 ;PUSH (r2) ;add r3, r0, 2001 ;PUSH (r3) ;add r4, r0, 2002 ;PUSH (r4) ;bsr BuscaMax ;stop LEA (r30, 0x0000F000) LEA (r8, ref) ;guarda en r8 ref LOAD (r9, max) ;guarda en r9 max LEA (r10, jj) ;guarda en r10 jj PUSH (r10) PUSH (r9) PUSH (r8) bsr BuscaMax ;saltar al código BuscaMax addu r30, r30, 12 stop Main_Checksum: LEA (r30, 0x0000F000) LEA (r8, texto) ;guarda en r8 texto PUSH (r8) bsr Checksum addu r30, r30, 4 stop ;------------------------------------------------------------------------------------------------------------------------------- LongCad: PUSH (r1) ;dirección de retorno PUSH (r31) ;marco de pila or r31, r30, r30 or r29, r0, r0 ;inicializo el resultado(r29) a 0 ld r10, r31, 8 ;guarda la direccion de la cadena(r8) que esta en la posición 8 de la pila en r10 xor r20, r0, r0 ;inicializo el contador (r20) a 0 bucle_LongCad: ld.bu r21, r10, r20 ;carga el caracter que este en la posición que te data el contador cmp r17, r21, r0 ;guarda en r11 la comparación entre el caracter y NULL bb1 eq, r17, final ;si caracter == NULL entonces se va a final y sino sigue addu r20, r20, 1 ;sumas uno al contador br bucle_LongCad ;salto incondicional sin retorno(no modifica r1) a bucle_LongCad final: or r29, r20, r20 ;cargo en r29 el contado POP (r31) POP (r1) jmp (r1) BuscaCar: PUSH (r1) ;dirección de retorno PUSH (r31) ;marco de pila or r31, r30, r30 or r29, r0, r0 ;inicializo el resultado(r29) a 0 ld r10, r31, 8 ;guarda la dirección de C en r10 ld r11, r31, 12 ;guarda la dirección de ref en r11 ld r12, r31, 16 ;guarda la dirección de from en r12 ld r13, r31, 20 ;guarda la dirección de to en r13 xor r20, r0, r0 ;igualo el contador(r20) a 0 or r20, r12, r12 ;inicializo el contador a la posición en la que quiere que empiece a buscar(from) bucle_BuscaCar: ld.bu r21, r11, r20 ;carga el caracter de ref que este en la posición dada por el contador cmp r17, r13, r20 ;guarda en r10 la comparación para saber si el to = contador, es decir, para saber si se ha llegado al final bb1 eq, r17, fin_BuscaCar ;si to == contador entonces se va a fin_BuscaCar y si no sigue cmp r17, r21, r10 ;guarda en r15 la comparación entre el caracter cargado en r21 de ref con el caracter que se esta buscando(C) = r10 bb1 eq, r17, fin_BuscaCar ;si ref == C entonces se va a fin_BuscaCar y si no sigue addu r20, r20, 1 ;sumas uno al contador br bucle_BuscaCar ;salto incondicional sin retorno(no modifica r1) a bucle_BuscaCar fin_BuscaCar: or r29, r20, r20 ;cargo en r29 el contador POP (r31) POP (r1) jmp (r1) CoincidenCad: PUSH (r1) ;dirección de retorno PUSH (r31) ;marco de pila or r31, r30, r30 or r29, r0, r0 ;inicializo el resultado(r29) a 0 ld r11, r31, 8 ;guarda la dirección de cadena1 en r11 ld r10, r31, 12 ;guarda la dirección de cadena2 en r10 xor r20, r0, r0 ;inicializo el contador(r20) a 0 bucle_CoincidenCad: ld.bu r21, r11, r20 ;carga el caracter de cadena1 que este en la posición dada por el contador ld.bu r22, r10, r20 ;carga el caracter de cadena2 que este en la posición dada por el contador cmp r17, r21, r0 ;guardo en r12 la comparación para saber si la cadena1 a llegado al final bb1 eq, r17, fin_CoincidenCad ;si cadena1 a llegado al final entonces se va a fin_CoincidenCad y si no sigue cmp r17, r22, r0 ;guardo en r13 la comparación para saber si la cadena2 a llegado al final bb1 eq, r17, fin_CoincidenCad ;si cadena2 a llegado al final entonces se va a fin_CoincidenCad y si no sigue cmp r17, r21, r22 ;guarda en r14 la comparación del caracter de cadena1 con el caracter de cadena2 bb1 ne, r17, fin_CoincidenCad ;si cadena1 != cadena2 entonces se va a fin_CoincidenCad y si no sigue addu r20, r20, 1 ;sumas uno al contador br bucle_CoincidenCad ;salto incondicional sin retorno(no modifica r1) a bucle_CoincidenCad fin_CoincidenCad: or r29, r20, r20 ;cargo en r29 el contador POP (r31) POP (r1) jmp (r1) BuscaMax: PUSH (r1) ;dirección de retorno PUSH (r31) ;marco de pila or r31, r30, r30 or r29, r0, r0 ;inicializo el resultado(r29) a 0 ld r14, r31, 8 ;guarda la dirección de ref ld r15, r31, 12 ;guarda la dirección de max ld r4, r31, 16 ;guarda la dirección de jj xor r20, r0, r0 ;inicializo el contador(r20) a 0 xor r23, r0, r0 ;inicializo la variable donde voy a guardar la cadena más larga hasta el momento xor r28, r0, r0 ;inicializo r28(desplazamiento hasta la cadena más larga hasta el momento) a 0 xor r22, r0, r0 xor r27, r0, r0 xor r25, r0, r0 ld.bu r22, r14, r15 ;carga el caracter de ref que este en la posición dada por max addu r27, r14, r15 ;subcadena bucle_BuscaMax: or r26, r0, r0 ;inicializo r26 a 0 cmp r17, r20, r15 ;guarda en r17 la comparación entre el contador y max bb1 eq, r17, fin_BuscaMax ;si son iguales se va a fin_bucle y si no sigue cmp r17, r20, 255 bb1 eq, r17, fin_BuscaMax ;si la subcadena llega al tamaño máximo(255) entonces va a fin_BuscaMax y sino sigue PUSH (r20) PUSH (r15) ;cargo r15(el valor de max) como to PUSH (r20) ;cargo r20(el contador) como from PUSH (r14) ;cargo r14(la dirección de ref(la cadena)) como ref PUSH (r22) ;cargo r22(el caracter de ref que se encuentra en la posición dada por max) como C bsr BuscaCar POP (r22) POP (r14) POP (r20) POP (r15) POP (r20) or r20, r29, r29 ;guardo en r20 el resultado obtenido tras llamar a la subrutina BuscaCar cmp r17, r20, r15 ;si es igual el resultado obtenido tras llamar a la subrutina BuscaCar = to va a fin_BuscaMax bb1 eq, r17, fin_BuscaMax ;si no sigue addu r25, r14, r20 ;cargo la cadena de ref que este a partir de la posición dada por BuscaCar PUSH (r22) PUSH (r20) PUSH (r25) ;cargo r25(la cadena ref que empieza en la posición dada por BuscaCar) como cadena2 PUSH (r27) ;cargo r27(la cadena de ref que empieza en la posición dada por max) como cadena1 bsr CoincidenCad POP (r27) POP (r25) POP (r20) POP (r22) or r26, r29, r29 ;guardo el r26 el resultado obtenido tras llamar a la subrutina CoincidenCad addu r20, r20, 1 ;sumas uno al contador cmp r17, r23, r26 bb1 gt, r17, bucle_BuscaMax ;si r23 > r26 vuelve a bucle_BuscaMax y si no sigue or r23, r26, r0 ;actualizo r23 a r26 ya que es la cadena más larga hasta el momento cmp r17, r20, r0 bb1 eq, r17, jj_cero ;si r20 es igual a \0 entonces que se vaya a jj_0 or r28, r20, r20 ;actualizo r28() al valor devuelto por BuscaCar subu r28, r28, 1 ;resto 1 al valor que se va a guardar en jj ya que se suma 1 a r20 antes de comprobar cual es mayor y esa modificación no interasa guardarla br bucle_BuscaMax ;salto incondicional sin retorno(no modifica r1) a bucle_BuscaMax jj_cero: or r28, r0, r0 ;inicializo a 0 r28 para poner a 0 el jj st r28, r4, 0 ;guardo en jj el valor obtenido en BuscaCar ya que es la posición desde donde empieza la cadena fin_BuscaMax: or r29, r23, r23 ;cargo en r29 la cadena más larga encontrada POP (r31) POP (r1) jmp (r1) Checksum: PUSH (r1) ;dirección de retorno PUSH (r31) ;marca de pila or r31, r30, r30 or r29, r0, r0 ld r10, r31, 8 ;guardo el texto(la cadena) en r10 xor r20, r0, r0 ;se inicializa r20 que es donde se va a guardar la suma de comprobación xor r9, r0, r0 ;r9(es el desplazamiento de la cadena) se inicializa a 0 xor r23, r0, r0 ;r23(donde se va a guardar el resultado de LongCad) se inicializa a 0 xor r25, r0, r0 ;contador para saber cuantas veces a guardado los 4 bytes xor r27, r0, r0 ;variable donde guardo un 4 inicializada a 0 addu r27, r27, 4 ;r27 = 4 PUSH (r20) ;para no reescribir r20 PUSH (r10) ;cargo r10(el texto) como cadena bsr LongCad POP (r10) POP (r20) or r23, r29, r29 ;guardo el resultado optenido en LongCad en r23 divu r21, r23, 4 ;guarda en r21 la división entre el resultado dado en LongCad y el número de bytes que tiene una palabra mulu r22, r21, 4 ;guarda en r22 la multiplicación de r21 * 4 subu r24, r23, r22 ;guarda en r24 el resto de la división entre el resultado dado en LongCad y el número de bytes que tiene una palabra cmp r17, r24, 0 ;se compara si el resto es 0 bb1 ne, r17, bucle_conResto ;se va a bucle ;hay que poner los 0s necesarios en la última de 4 bits y luego ya que pase a bucle_Checksum: ld r11, r10, r9 ;en r11 se guardan los 4 bytes a partir del desplazamiento r9 addu r20, r20, r11 ;va sumando los 4 bytes que se van guardando addu r25, r25, 1 ;suma 1 ya que ha guardado 4 bytes addu r9, r9, 4 ;realiza un desplazamiento de 4 para conseguir los siguientes 4 bytes cmp r17, r25, r21 ;compara si el contador de veces que se han guardado 4 bytes y el cociente de la división bb1 ls, r17, bucle_Checksum ;son iguales br fin_Checksum bucle_conResto: ld r11, r10, r9 ;en r11 se guardan los 4 bytes a partir del desplazamiento r9 cmp r17, r25, r21 ;probablemente este bucle este mal bb1 eq, r17, ultima_palabra addu r20, r20, r11 ;va sumando los 4 bytes que se van guardando addu r25, r25, 1 ;suma 1 ya que ha guardado 4 bytes addu r9, r9, 4 ;realiza un desplazamiento de 4 para conseguir los siguientes 4 bytes cmp r17, r25, r21 ;compara si el contador de veces que se han guardado 4 bytes <= al cociente de la división bb1 ls, r17, bucle_conResto ;son iguales ultima_palabra: subu r24, r27, r24 mulu r24, r24, 8 mak r26, r11, r24 ;rellena de 0s el último de 4 bytes extu r26, r26, r24 addu r20, r20, r26 fin_Checksum: or r29, r20, r20 ;guardo la suma en r29 POP (r31) POP (r1) jmp (r1) Comprime: jmp(r1) Descomprime: jmp(r1) Verifica: jmp(r1)