0

I am trying to build a basic Mips program that takes a hardcoded string and converts lowercase chars to uppercase and vice-versa. I have managed to make two programs, one for upper to lower and one for lower to upper, but I cannot figure out how to combine the two. I believe the error in my program is coming from my checking for spaces and trying to skip over them, but I'm really not sure. With the nested case calls I am trying to mimic if-else logic

.data
string: .asciiz "\nThis Is A Test\n"
newline: .asciiz "\n"

.text
main:
    la  $t0, string # $t0 is pointer to first el of str, loading string
    li  $v0, 4      # print the original string
    la  $a0, string
    syscall
    
    li $s2, ' '
    li $v0, 4
    li $t0, 0

loop:
    lb $t1, string($t0)
    beq $t1, 0, exit
    beq $t1, $s2, neither
    
    j caseLower
   
caseLower:
    blt $t1, 'A', caseUpper
    bgt $t1, 'Z', caseUpper
    addi $t1, $t1, 32
    sb $t1, string($t0)
    addi $t0, $t0, 1
    j loop
    
    
caseUpper:
    blt $t1, 'a', neither
    bgt $t1, 'z', neither
    addi $t0, $t0, -32 
    sb $t1, string($t0)
    addi $t0, $t0, 1
    j loop
    
neither:
    addi $t0, $t0, 1
    j loop
    
exit:
    li $t0, 4
    la $a0, string
    syscall

    li $v0, 10
    syscall

This is the output I get:


This Is A Test

this Is A Test

-- program is finished running --

The output I want for the second line of output is: tHIS iS a tEST

Erik Eidt
  • 23,049
  • 2
  • 29
  • 53
gogo
  • 53
  • 1
  • 12
  • 1
    You should be able to find this error by single step debugging, which is a simple process though also a critical skill for coding. Single stepping stops the program after each instruction (in assembly or after each statement in other languages). Your job is to verify the operation of the instruction that just ran: look at the register it updated, or memory to verify what you're expecting. Also, check flow control: that the proper next instruction is next, which you'll see by where the debugger is stopped. Debugging your own code should be your first go-to. – Erik Eidt Feb 14 '22 at 23:48
  • 2
    There's no need to jump to the next line, as in `j caseLower` -- just remove that. You can leave the label, `caseLower:`, if you like it for documentary purposes, but once you remove that `j caseLower`, the label becomes no longer used. – Erik Eidt Feb 14 '22 at 23:49
  • 1
    Way over-complicated, just detect alphabetic and XORI to flip the lower-case bit. Like in [How to access a char array and change lower case letters to upper case, and vice versa](https://stackoverflow.com/a/35936844) for x86. See also [What is the idea behind ^= 32, that converts lowercase letters to upper and vice versa?](https://stackoverflow.com/a/54585515) – Peter Cordes Feb 15 '22 at 03:46

1 Answers1

1

addi $t0, $t0, -32 is faulty.

It should be addi $t1, $t1, -32 .

.data
string: .asciiz "\nThis Is A Test\n"
newline: .asciiz "\n"

.text
main:
    la  $t0, string # $t0 is pointer to first el of str, loading string
    li  $v0, 4      # print the original string
    la  $a0, string
    syscall
    
    li $s2, ' '
    li $v0, 4
    li $t0, 0

loop:
    lb $t1, string($t0)
    beq $t1, 0, exit
    beq $t1, $s2, neither
    
    j caseLower
   
caseLower:
    blt $t1, 'A', caseUpper
    bgt $t1, 'Z', caseUpper
    addi $t1, $t1, 32
    sb $t1, string($t0)
    addi $t0, $t0, 1
    j loop
    
    
caseUpper:
    blt $t1, 'a', neither
    bgt $t1, 'z', neither
    addi $t1, $t1, -32 
    sb $t1, string($t0)
    addi $t0, $t0, 1
    j loop
    
neither:
    addi $t0, $t0, 1
    j loop
    
exit:
    li $t0, 4
    la $a0, string
    syscall

    li $v0, 10
    syscall