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