• Compra una licencia de Windows 10/11 (10€) u Office (18€) al mejor precio u Office al mejor precio. Entra en este post con las ofertas
  • ¡Bienvenid@! Recuerda que para comentar en el foro de El Chapuzas Informático necesitas registrar tu cuenta, tardarás menos de 2 minutos y te dará valiosa información además de ayudarte en lo que necesites o pasar un rato agradable con nosotros.

De C a MIPS

Álvaro11

Nuevo
Registrado
28 Mar 2021
Mensajes
13
Puntos
1
Edad
21
Hola, quería saber si pueden ayudarme en este ejercicio de traducción de C a MIPS. Muchas gracias.

Traduzca la función a ensamblador que recibe como parámetro num_lineas (el número de líneas a dibujar, solicitado por teclado). Este parámetro se corresponde con el registro $a0. La función no devuelve ningún valor. A la hora de traducir print_string use la llamada al sistema (syscall) de MIPS correspondiente.

void dibujar_triangulo(int num_lineas)
{
int max_lineas = num_lineas;
if (num_lineas > MAX_LINEAS) {
max_lineas = MAX_LINEAS;
}
int blancos = max_lineas - 1 ;
int elementos = 1;
for (int i = 0; i < max_lineas; i++) {
for (int k = 0; k < blancos; k++) {
print_string(" ");
}
for (int k = 0; k < elementos; k++) {
print_string("#");
}
print_string("\n");
blancos = blancos - 1;
elementos = elementos + 2;
}
}
 
¿Y qué has probado? ¿Dónde tienes el problema exactamente?
 
Hola, quería saber si pueden ayudarme en este ejercicio de traducción de C a MIPS. Muchas gracias.

Traduzca la función a ensamblador que recibe como parámetro num_lineas (el número de líneas a dibujar, solicitado por teclado). Este parámetro se corresponde con el registro $a0. La función no devuelve ningún valor. A la hora de traducir print_string use la llamada al sistema (syscall) de MIPS correspondiente.

void dibujar_triangulo(int num_lineas)
{
int max_lineas = num_lineas;
if (num_lineas > MAX_LINEAS) {
max_lineas = MAX_LINEAS;
}
int blancos = max_lineas - 1 ;
int elementos = 1;
for (int i = 0; i < max_lineas; i++) {
for (int k = 0; k < blancos; k++) {
print_string(" ");
}
for (int k = 0; k < elementos; k++) {
print_string("#");
}
print_string("\n");
blancos = blancos - 1;
elementos = elementos + 2;
}
}
Pon aquí lo que hayas intentado, una cosa es que te ayudemos y otra que te lo hagamos...
 
Aquí tenéis, perdonad.

EN C:

void dibujar_triangulo(int num_lineas)
{
int max_lineas = num_lineas;
if (num_lineas > MAX_LINEAS) {
max_lineas = MAX_LINEAS;
}
int blancos = max_lineas - 1 ;
int elementos = 1;
for (int i = 0; i < max_lineas; i++) {
for (int k = 0; k < blancos; k++) {
print_string(" ");
}
for (int k = 0; k < elementos; k++) {
print_string("#");
}
print_string("\n");
blancos = blancos - 1;
elementos = elementos + 2;
}
}

EN MIPS:

dibujar_triangulo: # a0 es num_lineas
# TODO
li $t1, 0
li $t2, 0
li $t3, 5
ble $t1, $t3, Blancos
li $t2, 5

Blancos: li $t4, -1
li $t5, 1

addiu $t0, $0, 0
addiu $t6, $0, 0
for1: bge $t0, $t2, for3

for2: bge $t6, $t4, for3
la $a0, str007
li $v0, 4
syscall

addiu $t6, $t6, 1
j for2

for3: bge $t6, $t5, finfor1

la $a0, str008
li $v0, 4
syscall

addiu $t6, $t6, 1
j for3

la $a0, str002
li $v0, 4
syscall

addiu $t4, $t4, -1
addiu $t5, $t5, 2
addiu $t0, $t0, 1
finfor1:
li $v0, 0
jr $ra

El problema es que más allá de una línea no se me imprime el asterisco. Esto creo que también lo necesitáis saber:

str002 = salto de línea
str007 = espacio
str008 = #
 
Aquí tenéis, perdonad.

EN C:

void dibujar_triangulo(int num_lineas)
{
int max_lineas = num_lineas;
if (num_lineas > MAX_LINEAS) {
max_lineas = MAX_LINEAS;
}
int blancos = max_lineas - 1 ;
int elementos = 1;
for (int i = 0; i < max_lineas; i++) {
for (int k = 0; k < blancos; k++) {
print_string(" ");
}
for (int k = 0; k < elementos; k++) {
print_string("#");
}
print_string("\n");
blancos = blancos - 1;
elementos = elementos + 2;
}
}

EN MIPS:

dibujar_triangulo: # a0 es num_lineas
# TODO
li $t1, 0
li $t2, 0
li $t3, 5
ble $t1, $t3, Blancos
li $t2, 5

Blancos: li $t4, -1
li $t5, 1

addiu $t0, $0, 0
addiu $t6, $0, 0
for1: bge $t0, $t2, for3

for2: bge $t6, $t4, for3
la $a0, str007
li $v0, 4
syscall

addiu $t6, $t6, 1
j for2

for3: bge $t6, $t5, finfor1

la $a0, str008
li $v0, 4
syscall

addiu $t6, $t6, 1
j for3

la $a0, str002
li $v0, 4
syscall

addiu $t4, $t4, -1
addiu $t5, $t5, 2
addiu $t0, $t0, 1
finfor1:
li $v0, 0
jr $ra

El problema es que más allá de una línea no se me imprime el asterisco. Esto creo que también lo necesitáis saber:

str002 = salto de línea
str007 = espacio
str008 = #
La syscall para imprimir un carácter es la 11, no la 4. La 4 se usa para imprimir un string terminado en '\0', para ello debes pasar en $a0 la dirección de este. Si str00x son variables en la seccion .data, entonces está bien.
Fallos que veo:
  1. Cuando en t4 asignas el valor para los blancos, le asignas un -1 y no max_lineas - 1.
  2. Esto es más consejo que fallo, en ensamblador, es recomendable etiquetar cada cosa, ya que despues es un lío de leer. Por ejemplo, si t4 es int blancos, deberias indicarlo.
  3. Depues de j for2 deberías poner a 0 la k, como en el código original y desde for2 en caso de incumplirse la condición, saltar ahi y no a for3.
  4. Las instrucciones addiu $t0 y $t6, es mejor sustituirlas por mov. Ej: mov $t0, $s0
  5. El li $v0, 0 que hay despues de finfor1, entiendo que es por un return 0, cierto?
Yo aquí te dejo una solución que he desarrollado yo, partiendo de la tuya. A ver que te parece:
.globl __start
.data 0x10000000
MAX_LINEAS: .word 500 # Le he dado un valor arbitrario para este ejemplo
.text 0x00400000
__start:
li $a0, 5
mov $t1, $a0 # max_lineas
lw $s0, MAX_LINEAS
ble $t0, $s0, postfijar
mov $t1, $s0
postfijar:
mov $t2, $s0 # blancos
li $t3, 1 # elementos
li $s1, 0 # i
addi $t2, $t2, -1
for1:
bge $s1, $t1, return
li $s2, 0 # k
for2:
bge $s2, $t2, finfor2
li $a0, ' '
li $v0, 11
syscall
addi $s2, $s2, 1
j for2
finfor2:
li $s2, 0
for3:
bge $s2, $t3, finfor3
li $a0, '#' # Puedes poner directamente los caracteres o el codigo ASCII si lo prefieres
li $v0, 11
syscall
addi $s2, $s2, 1
j for3
finfor3:
li $a0, '\n'
li $v0, 11
syscall
addi $t2, -1
addi $t3, $t3, 2
addi $s1, $s1, 1
j for1
return:
li $v0, 0 # return 0?
jr $ra
Un saludo
 
Hola. Muchas gracias por tus indicaciones (efectivamente sí es un return 0 y haré caso de tus consejos :)). Tengo una pregunta de tu versión, ¿cómo puedo modificarla para que en vez de que te salga un triángulo fijo de 5 asteriscos puedas meter una variable entera que según el número de líneas que pongas pues te haga un triángulo con esas líneas exactas?
 
Hola. Muchas gracias por tus indicaciones (efectivamente sí es un return 0 y haré caso de tus consejos :)). Tengo una pregunta de tu versión, ¿cómo puedo modificarla para que en vez de que te salga un triángulo fijo de 5 asteriscos puedas meter una variable entera que según el número de líneas que pongas pues te haga un triángulo con esas líneas exactas?
Hola, pues tienes 2 opciones:
  1. Ir asignando el valor que quieras a $a0
  2. Implementar una rutina tal que asi:
.data 0x10000000
...
mensaje: .asciiz "Introduzca el número de líneas: "
nLineas: .space 4 # Espacio por si quieres guardar la variable
.text 0x00400000
__start:
la $a0, mensaje
li $v0, 4
syscall # Imprimimos el mensaje
li $v0, 5 # Syscall para leer un entero, este se guarda en $v0
syscall
mov $a0, $v0 # Movemos el entero leído al registro deseado
# Si: se quiere guardar el valor en nLineas para futuros propósitos, añadir
la $t0, nLineas
sw $v0, 0($t0)
# FinSi
jal dibujar_triangulo
dibujar_triangulo:
mov $t1, $a0 # max_lineas
...
Como ves he eliminado la instrucción li $a0, 5. En lugar de esta, recogemos el valor que el usuario introduce por teclado
Un saludo
 
Arriba