# write out the second struct
la $a0,agest # print "age:"
li $v0,4
syscall
lw $a0,0($s2) # print age
li $v0,1
syscall
li $v0,10 # return to OS
syscall
.data
pay: .word 24000 # rate of pay, in static memory
agest: .asciiz "age: "
Data that is contained in a struct is treated as a whole. In OO terms, it is treated like an object. It would be nice to have a subroutine that takes one of our structs as a parameter and prints it out. Let us write a subroutine that uses the Stack-based Calling Convention of Chapter 27. (It might not hurt you to review that chapter.)
Here is a small subroutine. For now, it only prints out
the age field of the argument struct.
It uses register $s0 so it must first push the
value in that register on the stack.
It does not call any other subroutine so it does not
need to push $ra.
(The trap handler calls are not normal subroutine calls.)
The argument is the address of the struct. A large struct can be passed as an argument to a subroutine by giving the subroutine the address of the struct. The various fields of the struct are accessed using displacements off the address.
.text
# Subroutine PStruct: print a struct
#
# Registers on entry: $a0 --- address of the struct
# $ra --- return address
#
# Registers: $s0 --- address of the struct
#
PStruct:
sub $sp,$sp,4 # push $s0
sw $s0,($sp) # onto the stack
move $s0,$a0 # safe copy of struct address
la $a0,agest # print "age:"
li $v0,4
syscall
lw $a0,0($s0) # print age
li $v0,1
syscall
add $sp,$sp,4 # restore $s0 of caller
lw $s0,($sp)
jr $ra # return to caller
.data
agest: .asciiz "age: "
For example, the age field of our struct is a displacement of
zero off of the struct's base address.
So this code gets the integer age using the statement
lw $a0,0($s0)