Programación General > ASM (Ensamblador)
RLE en ensamblador MIPS
manurodri189:
Tienes toda la razon, tio.
De hecho ya he acabado el programa, y se que funciona, gracias a la ejecucion paso a paso, y a lo que me pone en los registros.
El almacenar_salida, como preveia estaba mal y como se supone que entendí el código que me pasaste de decodificar, pues he visto que cometia los mismos errores que comentabas antes, lo de leer en vez de escribir y demas.
Aqui pongo el codigo que me ha quedado de almacenar_salida, pero ya te digo que funciona, porque lo he probado.
--- Código: ASM ---almacenar_salida: la $a0,encode1 la $a1,encode2 la $a3,encode or $t0,$zero,$a0 # encode1 or $t1,$zero,$a1 # encode2 or $t2,$zero,$a3 # encode while: lbu $t3,0($t0) # Carácter de "encode1" -> T3 addiu $t0,$t0,1 # Avanzamos puntero lbu $t4,0($t1) # Numero de "encode2" -> T4 beq $t3,$zero,finwhile #si es el caracter vacio acabo nop sb $t4,0($t2) #cargo el primer numero en encode addiu $t2,$t2,1 #avanzo el puntero de encode sb $t3,0($t2) #cargo el caracter en encode #avanzo todos los punteros addiu $t1,$t1,1 addiu $t2,$t2,1 b while #llamo a while de nuevo nop
Ahora solo tengo un pequeño problemilla que no se a que se debe. Y es a la hora de imprimir encode, y solo encode, porque los numeros me los imprime como caracteres extraños, no se si será por el syscall o porque, pero solo me pasa con el encode, ya que si imprimo el decode de la misma manera funciona perfectamente.
Lo imprimo así:
--- Código: ASM ---#Imprimir la matriz de salida codificada # Número de syscall ori $v0,$zero,4 # $a0 = buffer a imprimir la $a0,encode syscall
Y da como salida esto:
--- Citar ---Entrance String: aabbcc
String encode like: abc
String decode like: aabbcc
--- Fin de la cita ---
Te pego todo el programa acabado a falta de eso:
--- Código: ASM ---.dataEntrance: .space 80encode1: .space 40encode2: .space 40encode: .space 40decode: .space 80msg1: .asciiz "Please insert the String: "msg2: .asciiz "n"msg3: .asciiz "n String encode like: "msg4: .asciiz "n String decode like: "msg5: .asciiz "n Entrance String: ".text.globl main ## Main#main: ori $v0,$zero,4 la $a0,msg1 syscall #Almacenar el String en la matriz# Número de syscall ori $v0,$zero,8# $a0 = buffer para guardar la cadena la $a0,Entrance# $a1 = tamaño a leer ori $a1,$zero,80 syscall la $a0,Entrancejal eliminar_enternop ori $v0,$zero,4 la $a0,msg5 syscall #Imprimir la matriz# Número de syscall ori $v0,$zero,4# $a0 = buffer a imprimir la $a0,Entrance syscall ori $v0,$zero,4 la $a0,msg2 syscall ## Codificar#start: la $s0, Entrance la $s3, encode1 #almaceno la direccion de encode1 en s3, s3 es el puntero la $s4, encode2 #almaceno la direccion de encode2 en s4, s4 es el puntero or $a3,$zero,$s3 or $a2,$zero,$s4 sig_carac: lbu $s1, 0($s0) beq $s1, $zero, fin # Si es el carácter de final de cadena, ya terminamos add $a0,$zero,$s1 # Pasando el primer parámetro a la función procesar() jal procesar # Llamamos a la función procesar() addiu $a1,$s0,1 # Pasando el segundo parámetro a la función procesar() add $a0,$zero,$s1 #El carácter en $a0 addiu $v0,$v0,1 #sumamos 1 a v0 jal almacenar # Llamamos a la función almacenar() add $a1,$zero,$v0 # Ponemos el número de caracteres en $a1 beq $zero,$zero,sig_carac # Siguiente carácter diferente or $s0, $zero, $v1 # Actualizamos el puntero con el valor devuelto ## Exit#fin: jal almacenar_salida nop ori $v0,$zero,4 la $a0,msg3 syscall #Imprimir la matriz # Número de syscall ori $v0,$zero,4 # $a0 = buffer a imprimir la $a0,encode syscall ori $v0,$zero,4 la $a0,msg2 syscall jal decodificar nop ori $v0,$zero,4 la $a0,msg4 syscall #Imprimir la matriz # Número de syscall ori $v0,$zero,4 # $a0 = buffer a imprimir la $a0,decode syscall ori $v0,$zero,4 la $a0,msg2 syscall ori $v0,$zero,10 # Terminamos con exit syscall ## Procesar (habría que poner un nombre más explicativo :)## Recibe un carácter y el puntero a una cadena# Cuenta cuántos caracteres iguales al pasado consecutivos hay en la cadena# Devuelve en $v0 el número de caracteres iguales# y en $v1 el puntero al primer carácter diferente encontradoprocesar: add $v0, $zero, $zero # Inicializamos valores de retorno add $v1, $zero, $a1 add $t1, $zero, $zero # Contador de caracteres iguales consecutivosprocesar_iguales: lbu $t0, 0($a1) # Cargamos el siguiente carácter a comparar bne $a0, $t0, procesar_noiguales # Si no son iguales, terminamos addiu $a1, $a1, 1 # Apuntamos al siguiente carácter beq $zero, $zero, procesar_iguales addiu $t1, $t1, 1 # Si son iguales, aumentamos el contador en uno procesar_noiguales: add $v0, $v0, $t1 # Ponemos los valores de retorno add $v1, $v1, $t1 # Volvemos de la función jr $ra nop almacenar: sb $a0,0($a3) #meto el caracter en la primera direccion de a3 sb $a1,0($a2) #meto el contador en la primera direccion de a4 #avanzo el puntero addiu $a3,$a3,1 addiu $a2,$a2,1 # Volvemos de la función jr $ra nop almacenar_salida: la $a0,encode1 la $a1,encode2 la $a3,encode or $t0,$zero,$a0 # encode1 or $t1,$zero,$a1 # encode2 or $t2,$zero,$a3 # encode while: lbu $t3,0($t0) # Carácter de "encode1" -> T3 addiu $t0,$t0,1 # Avanzamos puntero lbu $t4,0($t1) # Numero de "encode2" -> T4 beq $t3,$zero,finwhile #si es el caracter vacio acabo nop sb $t4,0($t2) #cargo el primer numero en encode addiu $t2,$t2,1 #avanzo el puntero de encode sb $t3,0($t2) #cargo el caracter en encode #avanzo todos los punteros addiu $t1,$t1,1 addiu $t2,$t2,1 b while #llamo a while de nuevo nop finwhile: sb $zero, 0($t2) # Escribimos el carácter de fin de cadena jr $ra nop # void EliminarEnter(char* entrada)eliminar_enter: li $t1,0xAee_bucle: lbu $t0,0($a0) beq $t0,0xA,fin_ee addiu $a0,$a0,1 beq $zero,$zero,ee_bucle nopfin_ee: jr $ra sb $zero,-1($a0) decodificar: # cargamos los parámetros en otros registros la $a2,decode la $a0,encode1 la $a1,encode2 or $t0,$zero,$a0 # encode1 or $t1,$zero,$a1 # encode2 or $t2,$zero,$a2 # decode lbu $t3,0($t0) # Carácter de "encode1" -> T3 addiu $t0,$t0,1 # Avanzamos puntero decode_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 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, decode_while2 # Repetimos addiu $t4,$t4,-1 # Restamos uno al número de caracteres fin_dec_while2: lbu $t3,0($t0) # Carácter de "encode1" -> T3 beq $zero,$zero,decode_while1 addiu $t0,$t0,1 # Avanzamos puntero fin_dec_while1: sb $zero, 0($t2) # Escribimos el carácter de fin de cadena jr $ra nop
Saludos y muchas gracias de nuevo.
m0skit0:
--- Cita de: "manurodri189" ---Y es a la hora de imprimir encode, y solo encode, porque los numeros me los imprime como caracteres extraños
--- Fin de la cita ---
Esto ya lo comentamos :lol: Estás usando la llamada al sistema 4, que es para imprimir cadenas de caracteres, no vectores de números.
manurodri189:
Lo comentamos pero no me cuadra, si yo quiero que sean caracteres?
Como habria que hacer para imprimirlo entonces? un bucle que imprimar caracter a caracter? o como?
Salu2
Edito: me refiero a que si yo en vez de letras meto numeros, tal que 22233 la codificacion se imprimiria como:
#2#3 siendo la# caracter extraño
y la decodificacion me la hace bien, y tambien imprime numeros.
m0skit0:
--- Código: Text ---almacenar_salida: la $a0,encode1 la $a1,encode2 la $a3,encode :ph34r: :ph34r: :ph34r: veo que no quieres comprender cómo pasar parámetros a las funciones. Esto no va aquí, sino en la llamada a la función. Pero bueno, si no quieres hacer caso, tú mismo :P
--- Cita de: "manurodri189" ---Y es a la hora de imprimir encode, y solo encode, porque los numeros me los imprime como caracteres extraños
--- Fin de la cita ---
Tienes una ligera confusión sobre caracteres y valores. Lo que has escrito en encode1 son caracteres, independientemente de que representen números, letras, puntuaciones o ideogramas chinos. Pero en la memoria lo que tienes no es una 'A' o una '@', evidentemente, sino números, valores. En caso de los caracteres es el código ASCII. Por tanto la llamada del sistema de impresión de cadenas de caracteres relaciona cada código con el carácter que el corresponda (un dibujo al fin y al cabo) y lo imprime. Si queremos podemos cambiar las correspondencias código-carácter e incluso usar otros caracteres en vez de los estándar.
Pero si usamos encode2 en la llamada al sistema de impresión de cadenas de caracteres, tenemos un problema, porque lo que hay en memoria son números, no caracteres. Si le sumas a cada elemento de encode2 0x30 antes de imprimirlo, verás cómo sí que funciona bien :blink: A ver si sabes por qué... ;)
PD: y lo que dices que se ve 00 02 en los cuadraditos... ¡qué misterio! :lol: Son caracteres Unicode para los que tu sistema no encuentra fuente, por tanto te pone el código. Y como puedes ver son los números, pero no los caracteres (como te he explicado más arriba).
manurodri189:
Cierto tio, me cuesta aprender, no es que no te haga caso xDDDD ahora lo cambio.
Si le sumo 0x30 a cada numero antes de almacenarlo dices que lo imprime, tiene que ser porque en Hexadecimal el 32, es el 2, y el 36, el 6 y así, no?
Solamente tendria que meter la sentencia addiu aqui?
--- Código: ASM ---beq $t3,$zero,finwhile #si es el caracter vacio acabo nop addiu $t4,$zero,0x30 #sumo 30 para luego poder imprimirlo sb $t4,0($t2) #cargo el primer numero en encode addiu $t2,$t2,1 #avanzo el puntero de encode sb $t3,0($t2) #cargo el caracter en encode
La salida es esta:
--- Citar --- Entrance String: aaaabbbccc
String encode like: 0a0b0c
String decode like: aaaabbbccc
--- Fin de la cita ---
Porque me imprime 0s cuando tiene que imprimr los numeros correspondientes? supongo que la 0x30 no se puede sumar asi, verdad? como se le suma?
Salu2
Navegación
[#] Página Siguiente
[*] Página Anterior
Ir a la versión completa