See below.
convert
uses $s0
as a character pointer
because $a0
might be changed by conChar
.
You might think that it would be a good idea to look inside
conChar
to see if, in fact, it actually changes $a0
.
But this is a violation of modularity.
It is much better to have a calling convention, and to follow it,
than to make modules depend critically on each other's quirks.
For example, conChar
doesn't actually alter $a0
.
At least not now,
but later on, conChar
might be changed.
Then you (or the unfortunate programmer that inherited your program) would have to
look everywhere conChar
was used to see what assumptions were
made.
# convert -- convert a line to all capitals
#
# on entry:
# $a0 -- address of input buffer
# $a1 -- length of input buffer
#
# register use:
# $s0 -- pointer into character buffer
#
# on exit:
# no return values
.text .globl convert convert: sub $sp,$sp,4 # push the return address sw $ra,($sp) sub $sp,$sp,4 # push $s0 sw $s0,($sp) # for ( p=buffer; *p!=0; p++ ) move $s0,$a0 # p=buffer cloop: lbu $a0,($s0) # get a char from the string beqz $a0,endC # exit if null byte # argument a0: char to convert jal conChar # convert character sb $v0,($s0) # put converted char into string addu $s0,$s0,1 # p++ b cloop endC: lw $s0,($sp) # pop $s0 add $sp,$sp,4 lw $ra,($sp) # pop return address add $sp,$sp,4 jr $ra # return to caller