1

I'm trying to toggle a simple user given text from lower case to upper and vice versa. Example: “Hello” after running it becomes “hELLO” essentially toggling cases. The program currently only converts from lower case to upper. My question is, how can the transition from Uppercase to lowercase be implemented based on what's already written. Forgive me if I’m doing anything wrong. Am fairly new to this. This is what I currently have:

     .data
     promp:           .asciiz "Enter string: "
     str:             .space 81
     toogle_msg:      .asciiz "The result is "


     .text
     .globl main 

      main:
                 li $v0,4                   # syscall code to print
                 la $a0,promp               # promp message tag
                 syscall                    # print promp
                 li $v0, 8                  #syscall code to read string
                 li $a1, 81             # space for string          
                 la $a0, str                # str message tag
                 syscall                    # print

                 li $v0, 4
                 li $t0, 0

      loop:
                 lb $t1, str($t0)       
                 beq $t1, 0, exit           # go to exit if $t1=0
                 blt $t1, 'a', case     # go to case if $t1>a 
                 bgt $t1, 'z', case     # go to case if $t1<z
                 sub $t1, $t1, 32           # subtract 32 and save in $t1
                 sb $t1, str($t0)

      case: 
                 addi $t0, $t0, 1
                 j loop                 # go to loop

      exit:     
                 li $v0,4                   # syscall code to print
                 la $a0,toogle_msg          # toogle message tag
                 syscall                    # print toggle_msg
                 li $v0, 4                  # syscall code to print
                 la $a0, str                # str message tag
                 syscall                    # print str

                 li $v0, 10             # syscall code to exit
                 syscall                    # exit
pyfs
  • 13
  • 4
  • 1
    so what is it currently doing/not doing ? – lostbard Nov 26 '18 at 12:43
  • It's not capitalizing because it is not implemented in the program. My question is what should be written to add that functionality based on what's already coded. – pyfs Nov 26 '18 at 12:50
  • `xor` with `0x20` is the normal way to flip case. You only need one sub and one unsigned conditional branch to check if a byte is alphabetic, then an XOR. Or make it branchless with a `sub`+`sltu` / `shl` / `xor`, so you xor with 0x20 or 0 for non-alphabetic. See [How to access a char array and change lower case letters to upper case, and vice versa](https://stackoverflow.com/a/35936844) for an x86 version with plenty of text that explains the check / xor algorithm. – Peter Cordes Nov 26 '18 at 12:54
  • or if you want it really basic, lower to upper case is just adding the 32 instead of subtracting - so almost a duplicate of a section of the code already there – lostbard Nov 26 '18 at 13:04

1 Answers1

1

You look to be attempting to handle the case where it is a lower case letter which is fine - however you also need to handle the upper case - pretty much similar logic as you have, except for upper to lowercase.

Using you existing and adding minimal changes:

loop:
      lb $t1, str($t0)      
      beq $t1, 0, exit      # go to exit if $t1=0
      blt $t1, 'a', not_l_case      # go to case if $t1>a 
      bgt $t1, 'z', not_l_case      # go to case if $t1<z
      sub $t1, $t1, 32      # subtract 32 and save in $t1
      sb $t1, str($t0)
      j next_char
not_l_case: 
      blt $t1, 'A', not_u_case      # go to case if $t1>A 
      bgt $t1, 'Z', not_u_case      # go to case if $t1<Z
      add $t1, $t1, 32      # add32 and save in $t1
      sb $t1, str($t0)
not_u_case:
next_char:
      addi $t0, $t0, 1
      j loop

There are a number of other ways it could be implemented which may provide less code.

lostbard
  • 5,065
  • 1
  • 15
  • 17
  • Only `$at` (Assembler Temporary) gets used as a scratch reg by pseudo-instructions. `$t0` are call-clobbered in the calling convention, but they're not clobbered asynchronously or by any pseudo-instructions. Plus `sb` with a `symbol(register)` addressing mode in MARS or SPIM may assemble to a single instruction; I think they default to linking with static addresses in the low 16 bits of virtual address space, within range of the `imm16(reg)` MIPS addressing mode. Otherwise yeah, `sb` and `lb` could clobber `$at`. – Peter Cordes Nov 26 '18 at 13:10
  • What do you suggest then? I'm only using what I learned from my instructor... Thank you! – pyfs Nov 26 '18 at 13:11
  • @lostbard: I guess you noticed that yourself and removed that paragraph while I was typing my comment. – Peter Cordes Nov 26 '18 at 13:11
  • yeah I clobbered the register myself when I ran the code – lostbard Nov 26 '18 at 13:12
  • @lostbard: I was breaking my head trying to do this even though you made it seem very simple. Am very much a newbie. Definitely need to practice more. Thank you! – pyfs Nov 26 '18 at 13:24