3

I am trying to write a code which takes a,b,c or d as user input then branches them depending on what the user wants to. For some reason when I pick one of the 4 options the code just falls through all the branches and the program ends. Is it because there can only be one branch statement used?

.data
    #messages
    options: .asciiz "\nPlease enter a, b, c or d: "
    youEntered: .asciiz "\nYou picked: "
    bmiMessage: .asciiz "\nThis is the BMI Calculator!"
    tempMessage: .asciiz "\nThis converts Farenheit to Celcius!"
    weightMessage: .asciiz "\nThis converts Pounds to Kilograms!"
    sumMessage: .asciiz "\nThis is the sum calculator!"
    repeatMessage: .asciiz "\nThat was not a, b, c or d!"
    
    #variables
    input: .space   4 #only takes in one character
    
.text
main:
    #display "options" messsage
    li $v0, 4
    la $a0, options
    syscall
    
    #user input 
    li $v0, 8
    la $a0, input
    li $a1, 4
    syscall

    #display "youEntered" messsage
    li $v0, 4
    la $a0, youEntered
    syscall

    #display option picked
    li $v0, 4
    la $a0, input
    syscall

#branching
beq $a0, 'a', bmi
beq $a0, 'b', temperature
beq $a0, 'c', weight
beq $a0, 'd', sum


#end of main
li $v0, 10
syscall

bmi: 
    li $v0, 4
    la $a0, bmiMessage
    syscall

temperature:
    li $v0, 4
    la $a0, tempMessage
    syscall
    
weight: 
    li $v0, 4
    la $a0, weightMessage
    syscall
    
sum: 
    li $v0, 4
    la $a0, sumMessage
    syscall

repeat: 
    li $v0, 4
    la $a0, repeatMessage
    syscall

Anything will be helpful Thanks guys!

ggorlen
  • 44,755
  • 7
  • 76
  • 106
coder99
  • 43
  • 4
  • 3
    It's because that's what the cpu does. It continues ahead until told otherwise. You need to terminate your case blocks with an unconditional jump to wherever you want to continue. – Jester Apr 13 '21 at 22:47

1 Answers1

4

When you have code like:

label:
    # some code

another_label:
    # some more code

after # some code executes, control just continues on to # some more code. You probably want to jump unconditionally to your end of main code:

label:
    # some code
    j done

another_label:
    # some more code
    j done

# ...

done:
    # end of main

This, coupled with your branches, gives exclusive block semantics like a C if-else chain:

if (something) {
   // do something
}
else if (something_else) {
   // do something else
}

// end of main

Secondly, $a0 is an address, not a value, so the branch comparisons will fail. Try loading the value located at the address into a register, then using the register value to compare against 'a', 'b' and so on.

For example,

lb $t0, input
beq $t0, 'a', bmi
beq $t0, 'b', temperature
beq $t0, 'c', weight
beq $t0, 'd', sum
ggorlen
  • 44,755
  • 7
  • 76
  • 106
  • I even tried that, but it still doesnt print out the message in the branches – coder99 Apr 13 '21 at 23:04
  • Yes, I notice you're comparing against an address, not the value located at that address. See my update. – ggorlen Apr 13 '21 at 23:18
  • I tried loading the address into a register and made all the other changes, still not printing out the message in the branches. – coder99 Apr 13 '21 at 23:37
  • I updated the code and marked the changes above – coder99 Apr 13 '21 at 23:49
  • See my update. You're moving the address to `$s0` but never using `$s0` anywhere. Even if you did use it, it's still an address, same as `$a0`, not a byte. You need `lb` to load the byte at the address pointed to by `$a0`/`$s0`. – ggorlen Apr 13 '21 at 23:50
  • I used your example to 'lb' and for some reason it still does not work. Sorry im still new to assembly. P.s I updated the code above – coder99 Apr 13 '21 at 23:59
  • You removed all of the `syscall`s in your branches though so nothing will print. The `move` is still pointless because it's overwritten on the next line. After you get it working, I recommend returning to your original code so the question makes sense to future visitors (I may edit it for relevance). Don't worry, assembly is hard and we were all new at one point. – ggorlen Apr 14 '21 at 00:01
  • 2
    @coder99: Single-step through your asm in the debugger built-in to MARS, so you can see the path of execution and see actual values in registers to understand how your code is running. That's extremely helpful for spotting mistakes, compared to just looking at the output without opening the hood. – Peter Cordes Apr 14 '21 at 03:25