# write out the second struct la $a0,agest # print "age:" li $v0,4 # print string service syscall lw $a0,0($s2) # print age li $v0,1 # print int service 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 SPIM service requests do not change $ra
.)
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.
# Subroutine PStruct: print a struct # # Registers on entry: $a0 --- address of the struct # $ra --- return address # # Registers: $s0 --- address of the struct # .text PStruct: sub $sp,$sp,4 # push $s0 sw $s0,($sp) # onto the stack move $s0,$a0 # make a 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)
Why is register $s0
used in this routine?