############################################################################################### # MIPS example: Manipulating character strings # Function: Program to count upper case letters in a string stored in compacted form # i. e. 4 characters stored in each consecutive 32-bit memory word # Note that the program assume a little-endian underlying machine. (e.g. a x86-like # processor) This has no effect in the real processing of characters, but depending # on the size of the array may affect the processing of the last characters in the # string, if the underlying machine is big-endian. # # The ASCII code interval corresponding to the upper case letter is [65..90] (in decimal) # ############################################################################################### .data # add what follows to the data segment of the program str: .asciiz "Alo Mamae" # A null-terminated string # case: .word 0x0 # Variable to contain the value of upper/lower # case letters in string .text # Add what follows to the text segment of the program .globl main # Declare the label main to be a global one main: la $t0,str # register $t0 contains the address of the string lw $t1,0($t0) # get first part of the string andi $t6,$t1,0xff # isolate the first character using the 0x000000FF mask la $t3,case # get address of uppercase char counter lw $t4,0($t3) # get value of uppercase char counter. # Initially, it should be zero addiu $t5,$zero,4 # initializes the word char counter to 4 loop: blez $t6,end # external loop test: if char is 0x0, NULL char, # i.e. end of string addiu $t5,$t5,-1 # else, decrements word char counter and treat char sltiu $t2,$t6,65 # if char is smaller than letter "A" than it is not uppercase bne $t2,$zero,nxt_ch# if smaller than "A" get next char sltiu $t2,$t6,91 # if smaller than "Z"+1, than it is an uppercase letter beq $t2,$zero,nxt_ch# if bigger than "Z", get next char # addiu $t4,$t4,1 # if here, Bingo!, found one uppercase char. #Increment case counter nxt_ch: beq $t5,$zero,endw # if current word totally treated, jump to endw addu $t6,$t1,$zero # else, retrieve current word srl $t6,$t6,8 # shift eight bits to the right, to put the next # char as the least significant byte addu $t1,$t6,$zero # update current word, since there can be chars left andi $t6,$t6,0xff # isolates the relevant char j loop # and go back treat this char endw: addiu $t0,$t0,4 # increment string pointer lw $t1,0($t0) # get next char bundle andi $t6,$t1,0xff # isolates its first char addiu $t5,$zero,4 # j loop # go back treat this char end: sw $t4,0($t3) # just store counter of uppercase letters in case # The program is finished. Exit. li $v0,10 # system call for exit syscall # Exit!