我正在做一个Pascal Triangle来练习MIPS,但是当我必须做递归函数时,我的代码会中断。我不知道要做代码中标记的return语句:
首先,我将展示我正在翻译的C代码,最后,您可以看到冲突的退货声明(已标记)
// C Language
#include <stdio.h>
int trianguloPascal(int i, int k);
int main(void) {
int num, i, j, k;
printf("Introduce el número de filas: ");
scanf("%i", &num);
for (i = 0; i < num; i++) {
for (j = num; j > i; j--) {
printf(" ");
}
for (k = 0; k <= i; k++) {
printf("%6d", trianguloPascal(i, k));
}
printf("\n");
}
return 0;
}
int trianguloPascal(int i, int k) {
if ((i == 0) || (k == 0) || (i == k)) {
return 1;
} else {
///////////////////////////////////
// THIS IS THE CONFLCTING RETURN //
///////////////////////////////////
return (trianguloPascal(i-1, k-1) + trianguloPascal(i-1, k));
}
}
现在,我将展示MIPS代码,最后,您可以看到冲突的地方,我尝试执行此冲突的返回语句(已标记)
// MIPS Languaje
.data
var_i: .word 0
var_j: .word 0
var_k: .word 0
var_num: .space 4
msg_pedirNumeroFilas: .asciiz "Introduce el número de filas: "
msg_espacioCorto: .asciiz " "
msg_espacioLargo: .asciiz " "
msg_saltoDeLinea: .asciiz "\n"
.text
# Función principal del programa
MAIN:
# Mostrar el mensaje de pedir un número de filas
la $a0, msg_pedirNumeroFilas # Cargamos la cadena de texto que vamos a mostrar
li $v0, 4 # Cargar en $v0 la llamada al sistema para 'Mostrar String'
syscall # Ejecutar la llamada al sistema
# Recoger el número de filas que desea el usuario
li $v0, 5 # Cargar en $v0 la llamada al sistema para 'Recoger Int'
syscall # Ejecutar la llamada al sistema
# Guardar en memoria el número de filas obtenido
sw $v0, var_num # Guardar en 'num' el número recogido anteriormente
# Cargamos de memoria las variables, almacenándolas en variables salvadas
lw $s0, var_i # Guardamos en $s0 la variable var_i
lw $s1, var_j # Guardamos en $s1 la variable var_j
lw $s2, var_k # Guardamos en $s2 la variable var_k
lw $s3, var_num # Guardamos en $s2 la variable var_num
# Guardamos en pila los valores de i, j, k, num
addi $sp, $sp, -16
sw $s0, 0($sp)
sw $s1, 4($sp)
sw $s2, 8($sp)
sw $s3, 12($sp)
# for (i = 0; i < num; i++)
li $s0, 0 # i = 0 para cada inicio del bucle FOR_I
FOR_I:
bge $s0, $s3, END_FOR_I # (i >= num) ? GOTO END_FOR_I : CONTINUE
# for (j = num; j > i; j--) {
move $s1, $s3 # j = num para cada inicio del bucle FOR_J
FOR_J:
ble $s1, $s0, END_FOR_J # (j <= i) ? GOTO END_FOR_J : CONTINUE
# Imprimir los espacios
la $a0, msg_espacioCorto # Cargamos la cadena de texto que vamos a mostrar
li $v0, 4 # Cargar en $v0 la llamada al sistema para 'Mostrar String'
syscall # Ejecutar la llamada al sistema
addi $s1, $s1, -1 # j -= 1
j FOR_J # Volvemos al bucle FOR_J
END_FOR_J:
# for (k = 0; k <= i; k++) {
li $s2, 0 # k = 0 para cada inicio del bucle FOR_K
FOR_K:
bgt $s2, $s0, END_FOR_K # (k > i) ? GOTO END_FOR_K : CONTINUE
# Imprimir los espacios
la $a0, msg_espacioLargo # Cargamos la cadena de texto que vamos a mostrar
li $v0, 4 # Cargar en $v0 la llamada al sistema para 'Mostrar String'
syscall # Ejecutar la llamada al sistema
# Llamada a la función recursiva
move $a0, $s0 # Pasar como primer agumento i
move $a1, $s2 # Pasar como segundo agumento k
jal TRIANGULO_PASCAL # Llamada a triangulo_pascal(i, k)
# Imprimir resultado devuelto
move $a0, $v0 # Cargamos la cadena de texto que vamos a mostrar
li $v0, 1 # Cargar en $v0 la llamada al sistema para 'Mostrar Int'
syscall # Ejecutar la llamada al sistema
addi $s2, $s2, 1 # k += 1
j FOR_K # Volvemos al bucle FOR_K
END_FOR_K:
# Imprimir un salto de línea
la $a0, msg_saltoDeLinea # Cargamos la cadena de texto que vamos a mostrar
li $v0, 4 # Cargar en $v0 la llamada al sistema para 'Mostrar String'
syscall # Ejecutar la llamada al sistema
addi $s0, $s0, 1 # i += 1
j FOR_I # Volvemos al bucle FOR_I
END_FOR_I:
# Cargamos de pila los valores de i, j, k, num
lw $s0, 0($sp)
lw $s1, 4($sp)
lw $s2, 8($sp)
lw $s3, 12($sp)
addi $sp, $sp, 16
EXIT: # Salir del programa
li $v0, 10 # Cargar en $v0 la llamada al sistema para 'Salir'
syscall # Ejecutar la llamada al sistema
END_EXIT:
END_MAIN:
# Función que obtiene los dígitos del triángulo de Pascal
TRIANGULO_PASCAL:
IF: # ((i == 0) || (k == 0) || (i == k)) ? GOTO ELSE : CONTINUE
beq $a0, 0, MULTIPLE_CONDITION_OK # (i == 0) ? GOTO MULTIPLE_CONDITION_OK : CONTINUE
beq $a1, 0, MULTIPLE_CONDITION_OK # (k == 0) ? GOTO MULTIPLE_CONDITION_OK : CONTINUE
bne $a0, $a1, ELSE # (i != k) ? GOTO ELSE : CONTINUE
MULTIPLE_CONDITION_OK:
li $v0, 1 # return 1
jr $ra
ELSE:
############################################
##### HERE I TRY DO RECURSIVE FUNCTION #####
############################################
move $t0, $a0
move $t1, $a1
addi $a0, $t0, -1 # i-1
addi $a1, $t1, 0 # k
j TRIANGULO_PASCAL
move $t5, $v0
addi $a0, $t0, -1 # i-1
addi $a1, $t1, -1 # k-1
j TRIANGULO_PASCAL
move $t6, $v0
add $t7, $t5, $t6
move $t7, $v0 # return $t7
jr $ra # Volvemos a la línea después de la llamada
END_IF_ELSE:
END_TRIANGULO_PASCAL:
我知道怎么解决这个问题?我已经搜索了很长时间的信息,但我无法解决这个问题。
谢谢。
PD:两个代码都是MCVE,因此将运行复制粘贴。
正如@Jester建议的那样,我已经改变了C递归返回语句,如:
int trianguloPascal(int i, int k) {
if ((i == 0) || (k == 0) || (i == k)) {
return 1;
} else {
///////////////////////////////////
// THIS IS THE CONFLCTING RETURN //
///////////////////////////////////
int tmp = 0;
tmp = trianguloPascal(i-1, k-1);
tmp += trianguloPascal(i-1, k);
return (tmp);
}
}
更新的TrianglePascalFunction MIPS代码是:
TRIANGULO_PASCAL:
IF: # ((i == 0) || (k == 0) || (i == k)) ? GOTO ELSE : CONTINUE
beq $a0, 0, MULTIPLE_CONDITION_OK # (i == 0) ? GOTO MULTIPLE_CONDITION_OK : CONTINUE
beq $a1, 0, MULTIPLE_CONDITION_OK # (k == 0) ? GOTO MULTIPLE_CONDITION_OK : CONTINUE
bne $a0, $a1, ELSE # (i != k) ? GOTO ELSE : CONTINUE
MULTIPLE_CONDITION_OK:
li $v0, 1 # return 1
jr $ra
ELSE:
li $t8, 0 # int tmp = 0
move $t0, $a0 # $t0 = i
move $t1, $a1 # $t1 = k
addi $a0, $t0, -1 # i-1
addi $a1, $t1, -1 # k-1
j TRIANGULO_PASCAL
add $t8, $t8, $v0
addi $a0, $t0, -1 # i-1
addi $a1, $t1, 0 # k
j TRIANGULO_PASCAL
add $t8, $t8, $v0
move $v0, $t8 # return $t8
jr $ra # Volvemos a la línea después de la llamada
END_IF_ELSE:
END_TRIANGULO_PASCAL:
此代码获得的结果是:
1
1 1
1 1 1
1 1 1 1
1 1 1 1 1
所以我在ELSE语句中有一些错误,它始终返回1.为什么会这样?任何的想法?
答案 0 :(得分:0)
最后,我实现了MIPS代码的工作原理。我将展示我是如何做到的:
Ext.create('Ext.form.field.ComboBox', {
renderTo: Ext.getBody(),
fieldLabel: 'Select an option',
store: Ext.create('Ext.data.Store', {
fields: ['optionName', 'value'],
data: [
{
value: 1,
optionName: 'First Option'
},
{
value: 2,
optionName: 'Second Option'
},
{
value: 3,
optionName: 'Third Option'
}
]
}),
emptyText: 'Select...',
displayField: 'optionName',
valueField: 'value'
});
我希望它对那些和我有同样问题的人有用。