Example on Procedure Call 

From Chapter 9 "A Programmer's View of Computer Architecture: with assembly language examples from MIPS RISC architecture," by Goodman and Miller, 1993

(Prepared by Karren Miller, Revised by Saeid Nooshabadi)
.data
array: .word 0:4
message: .asciiz "Enter integer: "

.text ; Executable code follows

; start of the program
__start:




_start: .global _start ; "_start" is required by the linker
.global main ; "main" is our main program

b main ; Start running the main program




main:
lda a1, array ; load the address of array into a1
bl fill_array ; branch to procedure fill_array



; procedure to get 4 integers from the user and put them
; into the array.

fill_array:

sub sp, sp, #8
str lr, [sp,#4]

mov a4, a1 ; the array address is in a4 now
 mov a2, 0
mov a3, 3
for: bgt a2, a, done_for

str a4, [sp,#0]
lda a1, message ; address of str string
bl print_string ; call procedure to print string

bl get_int ; returns integer in a1
ldr a4, [sp,#0] ; load array address
str a1, [a4], 4 ; store int in array and increamet a4
add a2, a2, #1
b for

done_for:
ldr lr, [sp,#4]
add sp, sp, #8
mov pc, lr



; Problem with the procedure as written: it ignores the
; fact that function get_int will also use the a-register
; for its own local variables. That might cause the values
; in registers a2, and a2 to be over rwritten.

; Solution: Have procedure fill_array save the values of
; t-registers in its activation record.
; AND, we don't need to save a1, since it always gets reset
; just before it is used. AND, can set a3 inside the
; loop just before it is used to avoid putting it in the
; activation record.

; Better implementation:


data
array: .word 0:4
message: .asciiz "Enter integer: "

.text ; Executable code follows

; start of the program
__start:




_start: .global _start ; "_start" is required by the linker
.global main ; "main" is our main program

b main ; Start running the main program




main:
lda a1, array ; load the address of array into a1
bl fill_array ; branch to procedure fill_array



; procedure to get 4 integers from the user and put them
; into the array.

fill_array:

sub sp, sp, #12
str lr, [sp,#8]

mov a4, a1 ; the array address is in a4 now
 mov a2, 0
for: mov a3, 3
bgt a2, a, done_for

str a4, [sp,#4]
lda a1, message ; address of str string
bl print_string ; call procedure to print string

str a2, [sp,#0] ; save a2 register
bl get_int ; returns integer in a1
ldr a2, [sp,#0] ; restore a2 register
ldr a4, [sp,#4] ; load array address
str a1, [a4], 4 ; store int in array and increamet a4
add a2, a2, #1
b for

done_for:
ldr lr, [sp,#8]
add sp, sp, #12
mov pc, lr