addi \$sp, \$sp, -4
lw \$s0 0(\$sp)
이게 필요int leaf_example(int g, int h, int i, int j)
{
int f;
f = (g + h) - (i + j);
return f;
}
add $t0, $a0, $a1 # (g + h)
add $t1, $a2, $a2 # (i + j)
sub $s0, $t0, $t1 # f = (g + h) - (i + j)
move $v0, $s0 # f를 return하기위해 $v0에 저장
jr $ra # $v0을 return 후 PC + 4로 jump
addi $sp, $sp, -4
sw $s0, 0($sp)
~~~
~~~
lw $s0, 0($sp)
addi $sp, $sp 4
leaf_example:
addi $sp, $sp, -4
sw $s0, 0($sp)
add $t0, $a0, $a1 # (g + h)
add $t1, $a2, $a2 # (i + j)
sub $s0, $t0, $t1 # f = (g + h) - (i + j)
move $v0, $s0 # f를 return하기위해 $v0에 저장
lw $s0, 0($sp)
addi $sp, $sp 4
jr $ra # $v0을 return 후 PC + 4로 jump
함수안에서 함수를 또 호출하게 되면 $ra가 꼬일 수 있어서 이 또한 $sp에 저장해야함
만약 Stack에 저장하지 않았다면, F1의 중간부분 jal F2에서 PC + 4인 lw $a0, 0($sp)이 $ra에 저장됨.
F1의 제일 마지막줄 jr $ra에서 F1을 빠져나가지 못하고 갇히게 됨.
$k0~$k1(26~27)은 커널에 의해 관리되어서 해당표에서 제외
void swap(int v[], int k)
{
int temp;
temp = v[k];
v[k] = v[k+1];
v[k+1] = temp
}
sll $t1, $a1, 2
add $t1, $t1, $a0 # $t1에 v[k]의 주소 할당
lw $t0, 0($t1) # temp에 v[k] load
lw $t2, 4($t1)
sw $t2, 0($t1) # v[k]에 v[k+1] load -> memory to memory는 lw, sw 세트
sw $t0, 4($t1) # v[k+1]에 temp store
jr $ra # void를 return하므로 $v0을 다루지는 않음
void sort (int v[], int n)
{
int i, j;
for (i = 0; i < n; i += 1) {
for (j = i - 1; j >= 0 && v[j] > v[j + 1]; j-=1) {
swap(v, j);
}
}
}
for (i = 0; i < n; i+=1)
에서 i=0
-> move $s0, $zero
이므로 move $s0, $zero
for1: slt $t0, $s0, $a1
beq $t0, $zero, exit1
~~~(body of 1th loop)~~~
addi $s0, $s0, 1
j for1
eixt1:
그다음 두번째 for문
addi $s1, $s0, -1
for2: slt $t0, $zero, $s1
beq $t0, $zero, exit2
sll $t1, $s1, 2
addi $t2, $t1, $a0
lw $t3, 0($t2)
lw $t4, 4($t2)
slt $t0, $t4, $t3
beq $t0, $zero, exit2
~~~(body of 2nd loop)~~~
addi $s1, $s1, -1
j for2
exit2:
swap(v, j);
는
move $a0, $s2 # $s2에 v의 시작주소이므로 첫번째 파라미터 $a0로 이동
move $a1, $s2 # $s2가 j이므로 두번째 파라미터 $a1로 이동
jal swap # swap(v,j) 호출
sort: addi $sp, $sp, -20
sw $ra, 16($sp)
sw $s3, 12($sp)
sw $s2, 8($sp)
sw $s1, 4($sp)
sw $s0, 0($sp)
~~~(body of procedure)
lw $s0, 0($sp)
lw $s1, 4($sp)
lw $s2, 8($sp)
lw $s3, 12($sp)
lw $ra, 16($sp)
addi $sp, $sp, 20
clear1(int array[], int size)
{
int i;
for ( i = 0; i < size; i += 1 )
array[i] = 0;
}
를 MIPS로 변환하면 (i $t0, array $a0, size $a1)
move $t0, $zero
for: sll $t1, $t0, 2
add $t1, $t1, $a0
sw $zero, 0($t1)
addi $t0, $t0, 1
slt $t2, $t0, $a1
bne $t2, $zero for
clear2(int *array, int size)
{
int *p;
for ( p = &array[0]; p < &array[size]; p = p + 1 )
*p = 0;
}
를 MIPS로 변환하면 (*p $t0, array $a0, size $a1)
move $t0, $a0 # &array[0]은 array의 시작주소이므로 $a0와 같은 의미
sll $t1, $t0, $a1
add $t1, $t1, $a0
for: sw $zero, 0($t0)
addi $t0, $t0, 4
slt $t2, $t0, $t1
bne $t2, $zero, for