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