Programación General > ASM (Ensamblador)

 RLE en ensamblador MIPS

<< < (16/17) > >>

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

[0] Índice de Mensajes

[#] Página Siguiente

[*] Página Anterior

Ir a la versión completa