2015-10-28 2 views
0

Mon code comporte deux parties; la première partie fait une fonction qui prend deux nombres et retourne leurs produits. Je crois que j'ai bien fait cette partie. La deuxième partie est où je ne suis pas sûr quel est le problème. Dans cette partie je dois faire une fonction qui trouve le nombre factoriel, et dans cette fonction, je dois utiliser la fonction de multiplication que j'ai faite dans la première partie. S'il vous plaît jeter un oeil à mon code et dites-moi ce que je fais mal.Une fonction imbriquée dans MIPS

.data 
Fa_message: .asciiz "\nFAIL TEST\n" 
Pa_message: .asciiz "\nPASS TEST\n" 

number1: .word 4 
number2: .word 5 
KnownAnswers: .word 20 
START: .word 16 

.text 

main: 
# taking in the numbers for calculation. 
lw $a0, number1 # $a0 =4 
lw $a1, number2 # $a1 =5 
lw $t0, KnownAnswers # $t0 =20 

jal func_multiply # calling the mulyiply function 

move $t4,$v0  # store the product for any further comparisons  
bne  $t0, $t4, FailT # did it fail the test? 
beq  $t0, $t4, PassT # did it pass the test? 

func_multiply: # the mulyiply function 
mul $v0, $a0, $a1 # $v0 = number1 * number2 
jr $ra 

FailT: # print "\nFAIL TEST\n" 
li $v0,4 
la $a0, Fa_message 
syscall 

PassT: # print "\nPASS TEST\n" 
li $v0,4 
la $a0, Pa_message 
syscall 

###---------------------(PART-2)------------------- 

lw $a0, number1 # load the number for the factorial procedure 
beq $a0, $zero, factorialDone # (if the number = 0), !0 = 1 
mul $a1, $a1, $zero # initializing $a1 
mul $a2, $a1, $zero # initializing $a2 
addi $a1, $a0, -1 # $a1 = (the entered number - 1) 
addi $a2, $a0, 0 # $a2 = the entered number 
jal findfactorial 
### 

#Stop 
li $v0, 10 
syscall 


    findfactorial: 


    jal func_multiply # calling the mulyiply function # mul $v0, $a0, $a1 # $v0 = number1 * number2 
    move $t4,$v0  # store the product in t4 for any further usage 
    addi $a0, $a0, -1 # $a1 = $a1-1 
    addi $a1, $a0, -1 
    bne $a1, $zero, findfactorial # enter a loop if $a1 does not equal 0 



    jr $ra 

    factorialDone: 
    addi $v0, $v0, 1 
    syscall 

Répondre

0

L'instruction jal modifie le registre $ra. Donc, si la fonction A appelle une fonction B, alors A doit sauvegarder et restaurer la valeur que $ra avait lors de la saisie de A afin qu'elle puisse retourner au bon endroit. Ceci est généralement fait en utilisant la pile comme stockage temporaire.

Vous pouvez pousser un registre sur la pile (enregistrer) comme ceci:

addi $sp, $sp, -4 
sw $ra, ($sp) 

et pop un registre de la pile (restaurer) comme ceci:

lw $ra, ($sp) 
addi $sp, $sp, 4 

Ensuite, il y a votre boucle findfactorial. Vous êtes le résultat de: défausser toutes les itérations précédentes, de sorte que votre résultat sera toujours 1 * 2 == 2. La boucle doit ressembler à ceci:

findfactorial: 
    jal func_multiply 
    move $a0,$v0 
    addi $a1, $a1, -1 
    bne $a1, $zero, findfactorial 

De cette façon, vous devez d'abord multiplier 4 par 3, puis 12 par 2, etc.


Il existe d'autres sources dans votre code. Par exemple, si vous passez à FailT vous ne quittez pas immédiatement le programme après l'impression du message - vous continuez à exécuter le code après PassT.

Aussi je ne suis pas sûr de ce que cela est censé faire:

factorialDone: 
addi $v0, $v0, 1 
syscall 

Si vous voulez exécuter syscall 1 (print_int), alors ceci est incorrect parce qu'il n'a pas mis en place correctement $v0 (il devrait être li $v0,1). Et si vous vouliez que cela imprime le résultat de votre calcul factoriel, cela ne se produira pas, car vous avez un jr $ra juste avant cela, donc la seule fois où vous finissez à factorialDone, c'est que number1 en contenait 0. De plus, vous auriez pour configurer $a0 avec la valeur que vous souhaitez imprimer.