Lec 06
Lec 06
Subroutine, Parameter
Passing, Activation Record,
Nesting and Recursion
Dr. A. Sahu
Dept of Comp. Sc. & Engg.
Indian Institute of Technology Guwahati
1
Outline
• Procedural abstraction
• Requirements
– Control, Data
– Nesting and Recursion
• Sorting example
Assembly Lang. Program (S=∑i)
.data
Prompt: .asciiz "Please enter a +integer: "
result1: .asciiz “Sum “
.text
# main program with var n: $s0, sum:$s1,i:$s2
main:
li $v0, 4 # issue prompt
la $a0, prompt
syscall
li $v0, 5 # get n from user
syscall
move $s0, $v0
for: blt $
$s0, $
$s2, endf # exit loop if n < i
add $s1, $s1, $s2 # add i to sum
add $s2, $s2, 1 # increment i
b for # continue loop
endf:
df li $ 0 4
$v0, # print
i t “S
“Sum i
is "
la $a0, result1
syscall
li $v0, 1 # print sum
move $a0,
$ 0 $$s1
1
syscall
li $v0, 10 # terminate the program 3
syscall
Procedural Abstraction
P(){} proc P
Q(){}
Main
proc Q
P();
Q();
What is required?
• Control flow (call and return)
• Data flow (p
(parameter ppassing)
g)
• Local and global storage allocation
• Take care of nesting
• Take care of recursion
Control flow ‐ call
p = &A[0]; la $t1, A
q = p + 99; addi $s2, $t1, 396
X: r = p + 1; X: addi $t2, $t1, 4
Y: xchg(g( ); Y: jjal xchgg # $ra
$ gets
g PC+4
r++; addi $t2, $t2, 4
if (r≤q) goto Y; ble $t2, $s2, Y
p++; addi $t1, $t1, 4
if (p<q) goto X; blt $t1
$t1, $s2
$s2, X
Control flow ‐ return
data
main
P code
Q
Nested calls
P( ); void P( ) { void Q( ) {
…Q( );…. ……..
return} return}
j lP
jal P
P: ….. Q
Q: …..
jal Q …. …..
jr $ra
$ jr $
$ra
save and
restore
t $
$ra
Nested call example
void min(int *p, *r){
p = &A[0]; Y: xchg(p, r);
q = p + 99; r++;
X: r = p + 1; if (r≤q) goto Y;
(p, r);
min(p, ); }
p++; void xchg(int *p,*r ) {
if (p<q) goto X; if (*p<*r)
( p< r) goto Z;
*p ↔ *r;
Z: return;
}
Nested call example ‐ main
p = &A[0]; la $a0, A
q = p + 99; addi $s2, $a0, 396
X: r = p + 1; X: addi $a1, $a0, 4
(p, r);
min(p, ); jjal min
p++; addi $a0, $a0, 4
if (p<q) goto X; blt $a0, $s
$s2,, X
Nested call example – proc min
void
d min(int
( *p,*r){
* * ){ min:
sw $ra, ra_save
Y: xchg(p, r); Y: jal xchg
r++; addi $a1, $a1, 4
if (r≤q) goto Y; ble $a1, $s2, Y
lw $ra, ra_save
} jr $ra
Recursive calls – control flow
void
d min(int
( *p,*r){
* * ){ min: push $ra
sw $ra, ra_save
xchg(p, r); jal xchg
r++; addi $a1, $a1, 4
if (r≤q) bgt $a1, $s2, R
min(p, r); jal min pop
p p$
$ra
R: lw $ra, ra_save
} jr $ra
Stack and push/pop operations
$sp
local data
saved
s registers
(if any)
return addr
arguments
$fp
Sorting example ‐ Main
const m = 20;
void main(void) {
int N, i; int X[m], Y[m];
coutt << "enter
" t th the countt off iintegers\n";
t \ " cin
i >> N;
N
cout << "enter the integers\n";
f ((i = 0; i < N; i++)) cin >> X[i];
for []
sort(X, Y, N);
cout << "sorted values : \n";
for (i = 0; i < N; i++) cout << Y[i] << " "; cout << endl;
}
Recursive merge sort procedure
void sort (int A[ ], int B[ ], int n) {
int A1[m], A2[m]; int n1, n2;
if (n == 1) B[0] = A[0];
else
l {
n1 = n / 2; n2 = n ‐ n1;
sort (A, A1, n1);
sort (A+n1, A2, n2);
merge (A1, A2, B, n1, n2);
}
}
Merge procedure
void merge (int P[ ], int Q[ ], int R[ ], int p, int q) {
int i, j, k;
k
i = j = k = 0;
while (i < p && j < q)
if (P[i] < Q[ j]) R[k++] = P[i++];
else R[k++] = Q[ j++];
while
hil (i < p)) R[k++]
[k ] = P[i++];
[i ]
while (j < q) R[k++] = Q[ j++];
}
Activation record for merge
void
d merge (int( P[[ ],
]
$sp i
int Q[ ], int R[ ],
locals
j
i t p, int
int i t q)) k
{ return addr
P
paraameters
int i, j, k;
k Q
…….. R
p
} q
Simplifying activation record
$sp return addr
dd
$sp i p
j q
k
return addr
a0 P
P
a1
1 Q
Q
a2 R
R
p
q t0 i
t1 j
t2 k
Activation record for sort
localss
int A1[m], A2[m]; A2
int n1, n2; n1
……… n2
return addr
paarametters
}
A
B
n
Part of merge procedure
….. return addr
dd llw $t3,
$t3 4($sp)
4($ )
while (i < p) p L: bge $t0, $t3, X
q muli $t4, $t0, 4
R[k++] = P[i++];
add $t4, $t4, $a0
…… lw $t6, 0($t4)
a0 P
addi $t0, $t0, 1
a1
1 Q
muli $t5, $t2, 4
a2 R
add $t5, $t5, $a2
sw $t6,
$t6 0($t5)
t0 i
addi $t2, $t2, 1
t1 j
jL
t2 k
X:
Calling merge
merge (A1, A2, B, n1, n2);
return addr addi $a0, $sp, 0
p addi
ddi $a1,
$ 1 $sp,
$ 80
q lw $a2, 176($sp)
A1 l $t8,
lw $t8 160($sp)
160($ )
a0 P sw $t8, ‐8($sp)
A2
a1
1 Q l $t8,
lw $t8 164($sp)
164($ )
n1 a2 R sw $t8, ‐4($sp)
n2
return addr t0 i addi
ddi $sp,
$ $sp,
$ ‐1212
A t1 j jal merge
B t2 k
n ….
merge: sw $ra, 0($sp)
Return from merge
return addr
p llw $ra,
$ 0($sp)
($ )
q
addi $sp, $sp, 12
A1 jr $ra
A2 a0 P
a1
1 Q
n1 a2 R
n2
return addr t0 i
A t1 j
B t2 k
n
Calling sort
sort (A, A1, n1);
A’
B’’ sort: sw $ra, 168($sp)
n’
…….
A1 l $t8,
lw $t8 172($sp)
172($ )
sw $t8, ‐12($sp)
A2 addi $t8,
$t8 $sp,
$sp 0
n1 sw $t8, ‐8($sp)
n2 lw $$t8,, 160($sp)
($ p)
return addr
sw $t8, ‐4($sp)
A
B addi $sp, $sp, ‐184
n jal sort
Return from sort
A’
B’’ llw $ra,
$ 168($sp)
($ )
n’
addi $sp, $sp, 184
A1 jr $ra
A2
n1
n2
return addr
A
B
n
Further work (lab exercise)
• Complete the assembly program for recursive merge
sort
• Write a p
pointer version ((C and assembly)
y)
• Include code to track the max stack size
• Reduce local array size to n and find improvement
• Write more space efficient program (C and
assembly),
y), still recursive