Programación General > ASM (Ensamblador)

 RLE en ensamblador MIPS

<< < (15/17) > >>

m0skit0:

--- Cita de: "manurodri189" ---Me has dicho que codificar funciona, pero creo que el almacenamiento en encode, no porque lo imprimo y no hace nada.
--- Fin de la cita ---
Funciona bien codificar y almacenar. Míra los valores en la memoria. Por tanto tienes mal el procedimiento de impresión.


--- Cita de: "manurodri189" ---También he puesto el nop debajo de beq, porque tambien consume 8 al igual que jal.
--- Fin de la cita ---
Todos los saltos son así.

¿Qué tal si me pones qué debes hacer para descodificar? En pseudocódigo, para ver.

manurodri189:
Ok, a ver si escribo bien el pseudocodigo:


--- Código: Text ---Mientras encode1 no sea fin de cadena.          meter el primer caracter de encode1 en decode.     avanzar el puntero de decode     restar 1 al primer numero de encode2   (porque ya hemos metido un caracter en el resultado)     si el primer numero de encode2 es cero            avanzar los punteros, encode1, encode2 y decoderepetirfin mientras. 
Es esto lo que quiero que haga, y creo que el procedimiento en mips es el correcto, no? creo que lo que tiene que fallar es algo de intrucciones.

Por cierto como es que hago mal el proceso de impresion?

Salu2

m0skit0:
Intenta usar sólo los registros $aX (preferiblemente sólo lectura) y $tX (puedes hacer con ellos lo que quieras) dentro de las funciones  ;)

Primero, se supone que el número de elementos de encode1 y encode2 es el mismo, y no vamos a verificar esto. Resumidamente: por cada carácter de encode1, escribirlo en decode tantas veces veces como indique el elemento correspondiente en encode2. El pseudo-código sería por tanto:


--- Código: Text ---Cargamos dirección de "encode1", "encode2" y "decode"Cargamos carácter de "encode1" y avanzamos punteroMientras no sea fin de cadena    Cargamos número de caracteres de "encode2" y avanzamos puntero    Mientras número de caracteres sea distinto de 0        Escribe carácter en decode y avanza puntero        Restar 1 al número de caracteres    Repetir    Cargamos carácter de "encode1" y avanzamos punteroRepetir 

manurodri189:
A ver que te parece la funcion:


--- Código: ASM ---decodificar:     la $a0,encode1    la $a1,encode2    la $a3,decode    lbu $a3,0($a0)             #cargo el caracter en decode    addiu $a3,$a3,1            #avanzo el puntero decode while2:     beq $a0,$zero,finwhile2    #si es el caracter vacio acabo    nop    lbu $a2,0($a1)             #cargo el numero    addiu $a1,$a1,1            #avanzo el puntero while3:     beq $a2,$zero,etiqueta   #salto a etiqueta si es igual a 0    nop        lbu $a3,0($a0)             #cargo el caracter en decode    addiu $a3,$a3,1            #avanzo el puntero decode    addiu $a2,$a2,-1           #a2-1 #le resto 1 al primer numero     b while3 etiqueta:     lbu $a3,0($a0)             #cargo el caracter en decode    addiu $a3,$a3,1            #avanzo el puntero decode     b while2 finwhile2: # Volvemos de la función    jr $ra    nop 
Pero creo que si mal no he entendido, que tendria que restar uno al contador ya que ya he metido uno a la matriz decode antes de entrar a los while, no es asi?.

Salu2

m0skit0:
:huh:  :P

Sigues haciendo los mismos errores <_< . Cargas punteros y los usas como caracteres, especificas mal las entradas de función (y eso que ni siquiera estamos usando la pila :P), te haces un lío con los registros, lees en vez de escribir en memoria, te olvidas de que la instrucción siguiente a los saltos se ejecuta antes que el salto (y eso que lo acabamos de hablar :P ). Las instrucciones están bien planteadas, pero tienes que estar más al loro de que estás haciendo mal. No hacer lo primero que se te ocurra, probarlo, y si no funciona, esperar a que yo te ponga la corrección. Si no funciona, mira a ver por qué, ejecuta paso a paso y ve viendo qué hace tu código y cómo debería hacerlo en realidad. Así es como realmente se aprende, y sí, aprender requiere un esfuerzo  :brickwall:

A ver, primero vamos a suponer que la función es (estilo C, que mola más  B) ): void decodificar(const char* caracteres, const BYTE* frecuencias, const char* cadena_decodificada), siendo evidentemente caracteres = encode1 cargado en $a0, frecuencias = encode2 cargado en $a1, cadena_decodificada = decode cargado en $a2, y no devuelve ningún valor (void), así que no hace falta cargar $v0 (el registro en el que ponen el valor de retorno) con ningún valor. Estos parámetros los recibe la función cuando empieza, y trabaja suponiendo que están bien cargados antes de ser llamada. decodificar() es una función, por tanto los parámetros se le pasan y no hay que cargarlos. Así si queremos utilizar la función con otros parámetros no tenemos que modificar la función en sí (aunque esto creo que ya lo he dicho... :D ). Espero haberme explicado mejor esta vez sobre cómo crear y usar funciones en ensamblador MIPS  ^_^

Por tanto el inicio de la función tendría que ser directamente la carga del primer carácter de encode1 (o caracteres como definimos en C), que debe estar ya cargado en $a0. Además fíjate que caracteres y frecuencias están definidos como const en el prototipo de la función, así que no debemos modificar esas cadenas. Aparte, tampoco es necesario modificar los valores de los registros $aX, así que los usaremos sólo para leer (como te indiqué en el post anterior).


--- Código: Text ---decodificar:    # cargamos los parámetros en otros registros    or $t0,$zero,$a0   # encode1    or $t1,$zero,$a1   # encode2    or $t2,$zero,$a2   # decode Cargamos cada $aX en su $tX correspondiente, así no tenemos que modificar los $aX para nada, y podemos decir que nuestra función mantiene esos registros sin modificar.
       

--- Código: Text ---    lbu $t3,0($t0)  # Carácter de "encode1" -> T3         addiu $t0,$t0,1  # Avanzamos puntero Cargamos el carácter del puntero móvil de encode1 a $t3.


--- Código: Text ---decod_while1:        beq $t3,$zero,fin_dec_while1  # Mientras no sea fin de cadena    nop    lbu $t4, 0($t1)  # Número de repeticiones del carácter    addiu $t1,$t1,1  # Avanzamos de elemento Aquí vamos recorriendo los carácteres de encode1 hasta encontrar el carácter de fin de cadena 0.


--- Código: Text ---decode_while2:    beq $t4,$zero,fin_dec_while2  # Mientras el número de caracteres no sea cero    nop    sb $t3, 0($t2)   # Escribimos el carácter en decode    addiu $t2,$t2,1  # Avanzamos el puntero móvil de decode    beq $zero,$zero dec_while2  # Repetimos    addiu $t4,$t4,-1  # Restamos uno al número de caracteres Mientras queden repeticiones, escribimos el caracter consecutivamente en la cadena decode.
   

--- Código: Text ---fin_dec_while2:        lbu $t3,0($t0)  # Carácter de "encode1" -> T3         beq $zero,$zero,decode_while1    addiu $t0,$t0,1  # Avanzamos puntero Siguiente carácter de encode1


--- Código: Text ---fin_dec_while1:    sb $zero, 0($t2)   # Escribimos el carácter de fin de cadena    jr $ra    nop No hay que olvidar poner un final de cadena en decode, porque si no no es una cadena de caracteres válida ;)

No lo he probado, hazlo tú (ve paso a paso y fíjate bien los valores que hay en memoria y los registros), y asegúrate de que le pasas bien los parámetros a la función en los registros $aX.

Si puedes decirme dónde fallaba tu código, estaría bien también, así analizas qué has hecho mal.

 :hola:

Navegación

[0] Índice de Mensajes

[#] Página Siguiente

[*] Página Anterior

Ir a la versión completa