Я просматривал прошлое задание и пытался следовать логике рекурсивных функций. Он просто передает вход в «факт», определяет, если> = 1, и снова передает его в цикл. В петле я запутался. Я понимаю, что при вызове функций часто бывает полезно сохранить данные с помощью sw и загрузить его с помощью lw, когда вы закончите. Однако цикл вызывает факт (который вызывает цикл снова) до ввода < 1. Как вы можете видеть в приведенном ниже коде, он постоянно сохраняет $ ra и ввод в том же месте. Обратите внимание, что код lw не используется до тех пор, пока рекурсия не будет выполнена.Понимание Recusion In MIPS
Как это не перезаписывать старые данные? Вернули старые данные? Если это так, то как выбираете только два элемента, достаточно много раз, когда рекурсия используется? Какова цель $ v0 в этом коде?
fact: slti $t0, $a0, 1 # test for n < 1, n is user input
beq $t0, $zero, L1 # if n >= 1, go to L1
li $v0, 1 # return 1
jr $ra # return to instruction after jal
L1: addi $sp, $sp, -8 # adjust stack for 2 items
sw $ra, 4($sp) # save the return address
sw $a0, 0($sp) # save the argument n
addi $a0, $a0, -1 # n >= 1; argument gets (n – 1)
jal fact # call fact with (n – 1)
lw $a0, 0($sp) # return from jal: restore argument n
lw $ra, 4($sp) # restore the return address
addi $sp, $sp, 8 # adjust stack pointer to pop 2 items
mul $v0, $a0, $v0 # return n * fact (n – 1)
jr $ra # return to the caller
Это то, на что мне было похоже сначала, но jal fact используется до того, как вызывается lw или addi $ sp, $ sp, 8. Разве это не привело бы к перезаписи в стеке? –
№ 'jal' - это просто прыжок, который также помещает текущий компьютер в' $ ra'. Если функция будет выполняться 8 раз, она будет сначала расширяться 8 раз, а затем она будет сокращаться 8 раз. –
Хорошо, тогда как насчет mul $ v0, $ a0, $ v0?Потому что это происходит после jal и lws, разве это не означает, что мы просто умножаем n на 1? –