Example of Procedure Call using Display to Manage RTE
Internal links
- Source code
-
- SPIM code
-
caller code,
callee start code,
callee return code
- Running the SPIM code
Source Code
Starting with the source code:
package main is body
ma: integer;
procedure a is -- proc level 1 begin
aa,ab: integer;
procedure b is -- proc level 2 begin
ba: integer;
procedure c is -- proc level 3 begin
ca,cb: integer;
begin
ca := ba + 1;
ma := ma + 1;
writeln(" ca = ",ca," ma = ",ma);
if ca <= -3 then
writeln(" c calls a");
a;
writeln(" ca = ",ca," ma = ",ma);
end if;
writeln(" return from c");
end; -- proc level 3 end
begin
ba := aa + 2;
writeln(" ba = ",ba," and then b calls c");
c;
writeln(" return from b: ba = ",ba);
end; -- proc level 2 end
begin
aa := ma - 4;
writeln(" aa = ",aa," and then a calls b");
b;
writeln(" return from a: aa = ",aa);
end; -- proc level 1 end
begin
ma := -2;
writeln("ma = ",ma,"and then main calls a");
a;
writeln("done in main: ma = ",ma);
end;
SPIM code
We want to examine the generated SPIM code to handle this translation:
# Register Usage:
# $s0 for global variables
# $s1 for level one procedure display
# $s2 for level two procedure display
# $s3 for level three procedure display
#
.text
.globl main
main:
la $s0, VARS
#
# Start Code
# Generate Assignment Statement
#
li $t0,-2
sw $t0,0($s0)
#
# Generate Writeln statement
la $a0, S3
li $v0, 4
syscall
li $v0, 1
lw $a0,0($s0)
syscall
la $a0, S2
li $v0, 4
syscall
la $a0, S0
li $v0, 4
syscall
jal L0 # jump to procedure a
#
# Generate Writeln statement
la $a0, S1
li $v0, 4
syscall
li $v0, 1
lw $a0,0($s0)
syscall
la $a0, S0
li $v0, 4
syscall
#
# Halt execution
li $v0 10
syscall
# PROCEDURE HEADER
#
L1:
#
# Start of level 3 procedure c
sw $ra, ($sp) # store return address
sw $s3, -4($sp) # store old level 3 display
move $s3, $sp # set new level 3 display to top of stack
addi $sp, -16 # move by AR size
# BODY OF THE PROCEDURE
# Generate Assignment Statement
#
lw $t0,-8($s2)
add $t0,$t0,1
sw $t0,-8($s3)
# Generate Assignment Statement
#
lw $t0,0($s0)
add $t0,$t0,1
sw $t0,0($s0)
#
# Generate Writeln statement
la $a0, S15
li $v0, 4
syscall
li $v0, 1
lw $a0,-8($s3)
syscall
la $a0, S14
li $v0, 4
syscall
li $v0, 1
lw $a0,0($s0)
syscall
la $a0, S0
li $v0, 4
syscall
#
# Generate If-Then statement
lw $t1,-8($s3)
li $t2,-3
sle $t1,$t1,$t2
beqz $t1,L3
#
# Generate Writeln statement
la $a0, S13
li $v0, 4
syscall
la $a0, S0
li $v0, 4
syscall
jal L0 # jump to procedure a
#
# Generate Writeln statement
la $a0, S12
li $v0, 4
syscall
li $v0, 1
lw $a0,-8($s3)
syscall
la $a0, S11
li $v0, 4
syscall
li $v0, 1
lw $a0,0($s0)
syscall
la $a0, S0
li $v0, 4
syscall
b L2
L3:
L2:
#
# End If
#
# Generate Writeln statement
la $a0, S10
li $v0, 4
syscall
la $a0, S0
li $v0, 4
syscall
# END OF PROCEDURE
addi $sp, 16 # move by AR size
lw $s3, -4($sp) # restore old level 3display
lw $ra, ($sp) # restore return address
jr $ra # return
# End of procedure c
# PROCEDURE HEADER
L4:
#
# Start of level 2 procedure b
sw $ra, ($sp) # store return address
sw $s2, -4($sp) # store old level 2 display
move $s2, $sp # set new level 2 display to top of stack
addi $sp, -12 # move by AR size
# BODY OF PROCEDURE STATEMENTS
# Generate Assignment Statement
#
lw $t0,-8($s1)
add $t0,$t0,2
sw $t0,-8($s2)
#
# Generate Writeln statement
la $a0, S9
li $v0, 4
syscall
li $v0, 1
lw $a0,-8($s2)
syscall
la $a0, S8
li $v0, 4
syscall
la $a0, S0
li $v0, 4
syscall
jal L1 # jump to procedure c
#
# Generate Writeln statement
la $a0, S7
li $v0, 4
syscall
li $v0, 1
lw $a0,-8($s2)
syscall
la $a0, S0
li $v0, 4
syscall
# END OF PROCEDURE
addi $sp, 12 # move by AR size
lw $s2, -4($sp) # restore old level 2display
lw $ra, ($sp) # restore return address
jr $ra # return
# End of procedure b
# HEADER OF PROCEDURE
L0:
#
# Start of level 1 procedure a
sw $ra, ($sp) # store return address
sw $s1, -4($sp) # store old level 1 display
move $s1, $sp # set new level 1 display to top of stack
addi $sp, -16 # move by AR size
# BODY OF PROCEDURE
# Generate Assignment Statement
#
lw $t0,0($s0)
li $t1,4
sub $t0,$t0,$t1
sw $t0,-8($s1)
#
# Generate Writeln statement
la $a0, S6
li $v0, 4
syscall
li $v0, 1
lw $a0,-8($s1)
syscall
la $a0, S5
li $v0, 4
syscall
la $a0, S0
li $v0, 4
syscall
jal L4 # jump to procedure b
#
# Generate Writeln statement
la $a0, S4
li $v0, 4
syscall
li $v0, 1
lw $a0,-8($s1)
syscall
la $a0, S0
li $v0, 4
syscall
# END OF PROCEDURE
addi $sp, 16 # move by AR size
lw $s1, -4($sp) # restore old level 1display
lw $ra, ($sp) # restore return address
jr $ra # return
# End of procedure a
#
# Finish up by writing out constants
.word 0
.data
CONST: #Constant storage area
S0: .asciiz "\n"
S1: .asciiz "done in main: ma = "
S2: .asciiz "and then main calls a"
S3: .asciiz "ma = "
S4: .asciiz " return from a: aa = "
S5: .asciiz " and then a calls b"
S6: .asciiz " aa = "
S7: .asciiz " return from b: ba = "
S8: .asciiz " and then b calls c"
S9: .asciiz " ba = "
S10: .asciiz " return from c"
S11: .asciiz " ma = "
S12: .asciiz " ca = "
S13: .asciiz " c calls a"
S14: .asciiz " ma = "
S15: .asciiz " ca = "
#
# Reserve space for global variables
.word 0
VARS: # space for Global Variables
.data
_ma: .word 0 # Offset at 0
-----------------------------------------------------------
Running the SPIM code
> spim
SPIM Version 6.2 of January 11, 1999
Copyright 1990-1998 by James R. Larus (larus@cs.wisc.edu).
All Rights Reserved.
See the file README for a full copyright notice.
Loaded: /opt/spim/bin/trap.handler
(spim) load "p295.s"
(spim) run
ma = -2and then main calls a
aa = -6 and then a calls b
ba = -4 and then b calls c
ca = -3 ma = -1
c calls a
aa = -5 and then a calls b
ba = -3 and then b calls c
ca = -2 ma = 0
return from c
return from b: ba = -3
return from a: aa = -5
ca = -3 ma = 0
return from c
return from b: ba = -4
return from a: aa = -6
done in main: ma = 0
(spim) exit