나는 과거 할당을 검토 중이었고 재귀 함수의 논리를 따르려고했습니다. 단순히 입력을 "사실"로 전달하고> = 1인지 판단하고 다시 루프로 전달합니다. 그것은 내가 혼란스러워하는 루프에 있습니다. 함수를 호출 할 때 sw를 사용하여 데이터를 저장하고 완료하면 lw로로드하는 것이 좋습니다. 그러나 루프는 사실 까지 fact (루프를 다시 호출 함)를 호출합니다. 1. 아래 코드에서 볼 수 있듯이 $ ra와 입력을 동일한 지점에 저장합니다. 재귀가 실제로 완료 될 때까지 lw 코드는 사용되지 않습니다.Recusion에 대한 이해 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 사실은 lw 또는 addi $ sp, $ sp, 8이 호출되기 전에 사용되었습니다. 스택에있는 내용을 덮어 쓰게하지 않으시겠습니까? –
아니요.'jal'은 현재 PC를'$ ra'에 넣는 점프에 불과합니다. 함수가 8 번 실행되면 먼저 8 번 확장되고 8 번 축소됩니다. –
그럼, mul $ v0, $ a0, $ v0는 어떨까요?그것은 jal과 lws 다음에 오는 것이기 때문에, 우리가 n에 1을 곱하고 있다는 것을 의미하지 않을 것입니까? –