📌 Programming Styles
✔️ Six Steps in Execution of a Procedure
✔️ Instruction for Calling a Procedure
jal $ra // jump and link, MIPS instruction에서 procedure call 위해 쓰임
-> $ra에 PC+4 값 저장, 다시 main routine으로 return
📌 Basic Procedure Flow
gcd (i,j);
-> MIPS
jal gcd // jump to routine gcd, caller는 i와 j를 procedure에 저장하기 위해 $a0와 $a1에 저장한다.
gcd: ''' // code to compute gcd, callee는 결과값을 $v0에 저장
jr $ra // return, caller $ra에 저장된 PC+4 주소값을 통해 main으로 돌아온다
📌 Spilling Registers
📌 Compiling a C Leaf Procedure - 가장 말단의 function
//C 코드
int leaf_ex (int g, int h, int i, int j)
{
inf f;
f = (g+h) - (i+j);
return f;
}
//MIPS - g,h,i,j는 $a0, $a1, $a2, $a3에 저장
leaf_ex: addi $sp, $sp, -8
sw $t1, 4($sp)
sw $t0, 0($sp)
add $t0, $a0, $a1
add $t1, $a2, $a3
sub $v0, $t0, $tq
lw $t0, 0($sp)
lw $t1, 4($sp)
addi $sp, $sp, 8
jr $ra
📌 Nested Procedures
//C 코드
int rt_1 (int i) {
if (i == 0)
return 0;
else
return rt_2(i-1); //인자값 1만큼 감소
}
//MIPS
caller: jal rt_1 //main routine으로부터 rt_1 호출, 이때 PC+4 -> $ra
next:
rt_1: bne $a0, $zero, to_2
add $v0, $zero, $zero // $v0에 0을 세팅해서 main routine으로 jump
jr $ra
to_2: addi $a0, $a0, -1
jal rt_2 // 새로운 procedure로 jump
jr $ra // PC+4 -> $ra
rt_2: '''
✔️ Nested Procedures Outcome
📌 Saving the Return Address
rt_1:bne $a0, $zero, to_2
add $v0, $zero, $zero
jr $ra
to_2:addi $sp, $sp, -8
sw $ra, 4($sp)
sw $a0, 0($sp)
addi $a0, $a0, -1
jal rt_2
bk_2:lw $a0, 0($sp)
lw $ra, 4($sp)
addi $sp, $sp, 8
jr $ra
📌 Compiling a Recursive Procedure
int fact (int n) {
if (n < 1)
return 1;
else
return (n * fact(n-1));
}
// factorial 정의되어 있으면 이 코드는 procedure 내에서 다시 한번 이 procedure가 똑같이 호출되는 상황
이 가정에서 n은 argument register $a0을 통해 전달이 되고, 각 procedure의 output은 $v0으로 전달됨
✔️ A Look at the Stack for $a0 = 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
L1:
addi $a0, $a0, -1
jal fact
bk_f:
lw $a0, 0($sp)
lw $ra, 4($sp)
addi $sp, $sp, 8
mul $v0, $a0, $v0
jr $ra
📌 Allocating Space on the Stack
📌 Allocating Space on the Heap
📌 MIPS Addressing Modes