n 계승을 계산하는 로직
C -> MIPS
int fact(int n) {
if (n < 1) {
return 1;
} else {
return (n * fact(n-1));
}
}
C언어
fact:
addi $sp, $sp, -8
sw $ra, 4($sp)
sw $a0, 0($sp)
slti $t0, $a0, 1
beq $t0, $zero L1
addi $v0, $zero, 1
addi $sp, $sp, 8
jr $ra
MIPS
L1:
addi $a0, $a0, -1
jal fact
lw $a0, 0($sp)
lw $ra, 4($sp)
addi $sp, $sp, 8
mul $v0, $a0, $v0
jr $ra
n = 2인 경우를 통해
이해해보자.
fact:
addi $sp, $sp, -8
sw $ra, 4($sp)
sw $a0, 0($sp)
slti $t0, $a0, 1
beq $t0, $zero L1
addi $v0, $zero, 1
addi $sp, $sp, 8
jr $ra
n=2
L1:
addi $a0, $a0, -1
jal fact
lw $a0, 0($sp)
lw $ra, 4($sp)
addi $sp, $sp, 8
mul $v0, $a0, $v0
jr $ra
sp
fact:
addi $sp, $sp, -8
sw $ra, 4($sp)
sw $a0, 0($sp)
slti $t0, $a0, 1
beq $t0, $zero L1
addi $v0, $zero, 1
addi $sp, $sp, 8
jr $ra
n=2
L1:
addi $a0, $a0, -1
jal fact
lw $a0, 0($sp)
lw $ra, 4($sp)
addi $sp, $sp, 8
mul $v0, $a0, $v0
jr $ra
n=2일 때 복귀주소
2
sp
fact:
addi $sp, $sp, -8
sw $ra, 4($sp)
sw $a0, 0($sp)
slti $t0, $a0, 1
beq $t0, $zero L1
addi $v0, $zero, 1
addi $sp, $sp, 8
jr $ra
n=2
L1:
addi $a0, $a0, -1
jal fact
lw $a0, 0($sp)
lw $ra, 4($sp)
addi $sp, $sp, 8
mul $v0, $a0, $v0
jr $ra
n=2일 때 복귀주소
2
n >= 1이기 때문에 L1를 실행한다.
sp
fact:
addi $sp, $sp, -8
sw $ra, 4($sp)
sw $a0, 0($sp)
slti $t0, $a0, 1
beq $t0, $zero L1
addi $v0, $zero, 1
addi $sp, $sp, 8
jr $ra
n=2 -> n=1
L1:
addi $a0, $a0, -1
jal fact
lw $a0, 0($sp)
lw $ra, 4($sp)
addi $sp, $sp, 8
mul $v0, $a0, $v0
jr $ra
n=2일 때 복귀주소
2
n=1로 변경하고 fact를 실행한다.
sp
fact:
addi $sp, $sp, -8
sw $ra, 4($sp)
sw $a0, 0($sp)
slti $t0, $a0, 1
beq $t0, $zero L1
addi $v0, $zero, 1
addi $sp, $sp, 8
jr $ra
n=1
L1:
addi $a0, $a0, -1
jal fact
lw $a0, 0($sp)
lw $ra, 4($sp)
addi $sp, $sp, 8
mul $v0, $a0, $v0
jr $ra
n=2일 때 복귀주소
2
n=1일 때 복귀주소
1
sp
fact:
addi $sp, $sp, -8
sw $ra, 4($sp)
sw $a0, 0($sp)
slti $t0, $a0, 1
beq $t0, $zero L1
addi $v0, $zero, 1
addi $sp, $sp, 8
jr $ra
n=1
L1:
addi $a0, $a0, -1
jal fact
lw $a0, 0($sp)
lw $ra, 4($sp)
addi $sp, $sp, 8
mul $v0, $a0, $v0
jr $ra
n=2일 때 복귀주소
2
n=1일 때 복귀주소
1
n >= 1이기 때문에 L1를 실행한다.
sp
fact:
addi $sp, $sp, -8
sw $ra, 4($sp)
sw $a0, 0($sp)
slti $t0, $a0, 1
beq $t0, $zero L1
addi $v0, $zero, 1
addi $sp, $sp, 8
jr $ra
n=1 -> n=0
L1:
addi $a0, $a0, -1
jal fact
lw $a0, 0($sp)
lw $ra, 4($sp)
addi $sp, $sp, 8
mul $v0, $a0, $v0
jr $ra
n=2일 때 복귀주소
2
n=1일 때 복귀주소
1
n=0으로 변경하고 fact를 실행한다.
sp
fact:
addi $sp, $sp, -8
sw $ra, 4($sp)
sw $a0, 0($sp)
slti $t0, $a0, 1
beq $t0, $zero L1
addi $v0, $zero, 1
addi $sp, $sp, 8
jr $ra
n=0
L1:
addi $a0, $a0, -1
jal fact
lw $a0, 0($sp)
lw $ra, 4($sp)
addi $sp, $sp, 8
mul $v0, $a0, $v0
jr $ra
n=2일 때 복귀주소
2
n=1일 때 복귀주소
1
n=0일 때 복귀주소
0
sp
fact:
addi $sp, $sp, -8
sw $ra, 4($sp)
sw $a0, 0($sp)
slti $t0, $a0, 1
beq $t0, $zero L1
addi $v0, $zero, 1
addi $sp, $sp, 8
jr $ra
n=0
L1:
addi $a0, $a0, -1
jal fact
lw $a0, 0($sp)
lw $ra, 4($sp)
addi $sp, $sp, 8
mul $v0, $a0, $v0
jr $ra
n=2일 때 복귀주소
2
n=1일 때 복귀주소
1
n=0일 때 복귀주소
0
n < 1이기 때문에
L1를 실행하지 않는다.
sp
fact:
addi $sp, $sp, -8
sw $ra, 4($sp)
sw $a0, 0($sp)
slti $t0, $a0, 1
beq $t0, $zero L1
addi $v0, $zero, 1
addi $sp, $sp, 8
jr $ra
n=0
L1:
addi $a0, $a0, -1
jal fact
lw $a0, 0($sp)
lw $ra, 4($sp)
addi $sp, $sp, 8
mul $v0, $a0, $v0
jr $ra
n=2일 때 복귀주소
2
n=1일 때 복귀주소
1
결과($v0) 1
n=0일 때 복귀주소
0
sp
fact:
addi $sp, $sp, -8
sw $ra, 4($sp)
sw $a0, 0($sp)
slti $t0, $a0, 1
beq $t0, $zero L1
addi $v0, $zero, 1
addi $sp, $sp, 8
jr $ra
n=0
L1:
addi $a0, $a0, -1
jal fact
lw $a0, 0($sp)
lw $ra, 4($sp)
addi $sp, $sp, 8
mul $v0, $a0, $v0
jr $ra
n=2일 때 복귀주소
2
n=1일 때 복귀주소
1
결과($v0) 1
n=0일 때 복귀주소
0
n=0일 때, 복귀주소 = n=1일 때, L1의 fact 호출한 다음 명령어
sp
fact:
addi $sp, $sp, -8
sw $ra, 4($sp)
sw $a0, 0($sp)
slti $t0, $a0, 1
beq $t0, $zero L1
addi $v0, $zero, 1
addi $sp, $sp, 8
jr $ra
n=0 -> n=1
L1:
addi $a0, $a0, -1
jal fact
lw $a0, 0($sp)
lw $ra, 4($sp)
addi $sp, $sp, 8
mul $v0, $a0, $v0
jr $ra
n=2일 때 복귀주소
2
n=1일 때 복귀주소
1
결과($v0) 1
n=0일 때 복귀주소
0
sp
fact:
addi $sp, $sp, -8
sw $ra, 4($sp)
sw $a0, 0($sp)
slti $t0, $a0, 1
beq $t0, $zero L1
addi $v0, $zero, 1
addi $sp, $sp, 8
jr $ra
n=1
L1:
addi $a0, $a0, -1
jal fact
lw $a0, 0($sp)
lw $ra, 4($sp)
addi $sp, $sp, 8
mul $v0, $a0, $v0
jr $ra
n=2일 때 복귀주소
2
n=1일 때 복귀주소
1
결과($v0) 1 -> 1*1 = 1
n=0일 때 복귀주소
0
sp
fact:
addi $sp, $sp, -8
sw $ra, 4($sp)
sw $a0, 0($sp)
slti $t0, $a0, 1
beq $t0, $zero L1
addi $v0, $zero, 1
addi $sp, $sp, 8
jr $ra
n=1
L1:
addi $a0, $a0, -1
jal fact
lw $a0, 0($sp)
lw $ra, 4($sp)
addi $sp, $sp, 8
mul $v0, $a0, $v0
jr $ra
n=2일 때 복귀주소
2
n=1일 때 복귀주소
1
결과($v0) 1
n=0일 때 복귀주소
0
n=1일 때, 복귀주소 = n=2일 때, L1의 fact 호출한 다음 명령어
sp
fact:
addi $sp, $sp, -8
sw $ra, 4($sp)
sw $a0, 0($sp)
slti $t0, $a0, 1
beq $t0, $zero L1
addi $v0, $zero, 1
addi $sp, $sp, 8
jr $ra
n=1 -> n=2
L1:
addi $a0, $a0, -1
jal fact
lw $a0, 0($sp)
lw $ra, 4($sp)
addi $sp, $sp, 8
mul $v0, $a0, $v0
jr $ra
n=2일 때 복귀주소
2
n=1일 때 복귀주소
1
결과($v0) 1
n=0일 때 복귀주소
0
sp
fact:
addi $sp, $sp, -8
sw $ra, 4($sp)
sw $a0, 0($sp)
slti $t0, $a0, 1
beq $t0, $zero L1
addi $v0, $zero, 1
addi $sp, $sp, 8
jr $ra
n=2
L1:
addi $a0, $a0, -1
jal fact
lw $a0, 0($sp)
lw $ra, 4($sp)
addi $sp, $sp, 8
mul $v0, $a0, $v0
jr $ra
n=2일 때 복귀주소
2
n=1일 때 복귀주소
1
결과($v0) 1 -> 1*2 = 2
n=0일 때 복귀주소
0
sp
fact:
addi $sp, $sp, -8
sw $ra, 4($sp)
sw $a0, 0($sp)
slti $t0, $a0, 1
beq $t0, $zero L1
addi $v0, $zero, 1
addi $sp, $sp, 8
jr $ra
n=2
L1:
addi $a0, $a0, -1
jal fact
lw $a0, 0($sp)
lw $ra, 4($sp)
addi $sp, $sp, 8
mul $v0, $a0, $v0
jr $ra
n=2일 때 복귀주소
2
n=1일 때 복귀주소
1
결과($v0) 2
n=0일 때 복귀주소
0
sp