Function MIPS中的嵌套函数

Function MIPS中的嵌套函数,function,assembly,nested,mips,Function,Assembly,Nested,Mips,我的代码有两部分;第一部分是创建一个函数,该函数接收两个数字并返回它们的产品。我相信我做得对。 第二部分是我不确定问题出在哪里。在这一部分中,我需要做一个求阶乘数的函数,在这个函数中,我必须使用我在第一部分中做的乘法函数。请看一下我的代码,告诉我我做错了什么 .data Fa_message: .asciiz "\nFAIL TEST\n" Pa_message: .asciiz "\nPASS TEST\n" number1: .word 4 number2: .word 5 KnownAn

我的代码有两部分;第一部分是创建一个函数,该函数接收两个数字并返回它们的产品。我相信我做得对。 第二部分是我不确定问题出在哪里。在这一部分中,我需要做一个求阶乘数的函数,在这个函数中,我必须使用我在第一部分中做的乘法函数。请看一下我的代码,告诉我我做错了什么

.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 

jal
指令修改
$ra
寄存器。因此,如果函数A调用函数B,则A必须保存并恢复输入A时,
$ra
的值,以便返回到正确的位置。这通常是使用堆栈作为临时存储来完成的

您可以按如下方式在堆栈上推送(保存)寄存器:

addi $sp, $sp, -4
sw $ra, ($sp)
lw $ra, ($sp)
addi $sp, $sp, 4
findfactorial:
    jal func_multiply 
    move $a0,$v0
    addi $a1, $a1, -1
    bne  $a1, $zero, findfactorial
然后从堆栈中弹出一个寄存器(还原它),如下所示:

addi $sp, $sp, -4
sw $ra, ($sp)
lw $ra, ($sp)
addi $sp, $sp, 4
findfactorial:
    jal func_multiply 
    move $a0,$v0
    addi $a1, $a1, -1
    bne  $a1, $zero, findfactorial

然后是
findFactory
循环。您将丢弃之前所有迭代的结果,因此您的结果将始终为1*2==2。循环应该如下所示:

addi $sp, $sp, -4
sw $ra, ($sp)
lw $ra, ($sp)
addi $sp, $sp, 4
findfactorial:
    jal func_multiply 
    move $a0,$v0
    addi $a1, $a1, -1
    bne  $a1, $zero, findfactorial
这样,你先把4乘以3,然后把12乘以2,以此类推


您的代码中还有其他一些问题。例如,如果您跳转到
FailT
,则在打印消息后不会立即退出程序-您只是在
PassT
之后继续执行代码

我也不确定这应该做什么:

factorialDone:
addi $v0, $v0, 1
syscall 
如果要执行syscall 1(
print\u int
),则这是不正确的,因为它没有正确设置
$v0
(应该是
li$v0,1
)。如果你想用它来打印阶乘计算的结果,那就不可能了,因为在这之前你有一个
jr$ra
,所以你在
factorialDone
结束的唯一时间是如果
number1
包含0。此外,还必须使用要打印的值设置
$a0