1	#####################################################################
     2	#   Title:   Demonstrate passing information on the stack
     3	#            Show how to "UpperCase" a string
     4	#   Author:  Bary W Pollack
     5	#   File:    UpCase.asm
     6	#   Date:    Apr. 3, 2008 - 1700
     7	#####################################################################

     8	       .data
     9	ttl:   .ascii  "\nDemonstrate passing info on the stack\n"
    10	       .asciiz "and show how to \"uppercase\" a string\n\n"
    11	get:   .asciiz "Please enter a string [Enter]: "
    12	put:   .asciiz "In upper case, the string is:  "
    13	buffr: .space   256     # space for 256 characters

    14	#####################################################################

    15	    .globl  main        # make main "global"
    16	    .text

    17	main:
    18	    li      $v0, 4      # syscall code for print string
    19	    la      $a0, ttl    # pointer to the string to be printed
    20	    syscall

    21	    li      $v0, 4      # syscall code for print string
    22	    la      $a0, get    # pointer to the string to be printed
    23	    syscall

    24	    li      $v0, 8      # syscall code for read string
    25	    li      $a1, 256    # Initial length of the buffer
    26	    la      $a0, buffr  # pointer to the buffer that will hold the string
    27	    syscall

    28	    addiu   $sp, $sp, -4 # provide space for the address of the buffer
    29	    la      $t0, buffr  # point to the string buffer
    30	    sw      $t0, 0($sp) # save it in the stacak
    31	    jal     UpperCase	# call UpperCase to "UpperCase" the string
    32	    addiu   $sp, $sp, 4 # readjust the stack

    33	    li	$v0, 4      # sycall code for put string
    34	    la	$a0, put	# pointer to the string to be printed
    35	    syscall

    36	    li      $v0, 4      # print string code
    37	    la      $a0, buffr  # address of the string to be printed
    38	    syscall

    39	    li      $v0, 10     # syscall code for EXIT
    40	    syscall

    41	#####################################################################
    42	#   Stack - Variable Cross Reference
    43	#     0: address of the string buffer
    44	#   $t0: pointer to the current character in the buffer
    45	#####################################################################

    46	UpperCase:
    47	    lw	$t0, 0($sp) # retrieve address of the string buffer
    48	    li      $a1, 'a'    # lower case a
    49	    li      $a2, 'z'    # lower case z
    50	loop:
    51	    lb	$t1, 0($t0) # grab next character
    52	    beqz    $t1, rtn    # if NUL, then quit...
    53	    blt	$t1, $a1, nxt  # skip conversion if < 'a'
    54	    bgt     $t1, $a2, nxt  # skip conversion if > 'z'
    55	    andi    $t1, $t1, 0xDF # mask with 1101 1111
    56	    sb	$t1, 0($t0) # save the updated character
    57	nxt:
    58	    addiu	$t0, $t0, 1 # point at next character
    59	    j       loop        # go back to start of loop
    60	rtn:
    61	    jr	$ra		# return to caller

    62	    .end