1

I am trying to determine the lowest of 3 numbers.

I am using slt to compare 2 numbers at a time.

I am using beq and bne, and comparing them to $zero (because the result of slt is either 0 or 1, and register $zero holds the constant 0). By using beq and bne, I am trying to jump to the specific label that will ultimately print the lowest of the three.

I am puzzled that all of the label messages are getting printed. Below is my code. Can someone help me identify why all cases are printing?

# compare $s0 < $s1 
slt      $t0, $s0, $s1                   # if $s0 < $t1
bne      $t0, $zero, compare_s0_s2      # $t0 == 1, compare $s0 < $s2
beq      $t0, $zero, compare_s1_s2      # $t0 == 0, compare $s1 < $s2

# compare $s0 < $s2
compare_s0_s2:
slt     $t1, $s0, $s2                    # if $s0 < $s2
bne     $t1, $zero, print_lowest_s0     # $t1 == 1, print $s0
beq     $t1, $zero, print_lowest_s2     # $t1 == 0, print $s2

# compare $s1 < $s2
compare_s1_s2:
slt     $t2, $s1, $s2                   # if $s0 < $s2
bne     $t2, $zero, print_lowest_s1    # $t2 == 1, print $s1
beq     $t2, $zero, print_lowest_s2    # $t2 == 0, print $s2


# print $s0
print_lowest_s0:
li  $v0, 1
la  $a0, ($s0)
syscall

# print $s1
print_lowest_s1:
li  $v0, 1
la  $a0, ($s1)
syscall

# print $s2
print_lowest_s2:
li  $v0, 1
la  $a0, ($s2)
syscall
Bobemius
  • 21
  • 4
  • If you just want to print the lowest without caring which position it came from, you only need 2 branches: one to pick the lowest out of `$s0` and `$s1` and put it in `$a0`, then another to either `move $a0, $s2` or not. And one print-int syscall that prints that min. Duplicating that is just over-complicating things. – Peter Cordes Nov 11 '21 at 18:48
  • In general, duplicate of [what will be the corresponding structure of if..else in MIPS?](https://stackoverflow.com/q/39783738) – Peter Cordes Oct 25 '22 at 15:32

1 Answers1

1

I figured it out! The reason why is was printing all cases was because my syntax was incorrect! I translated my conditional wrong.

If you notice, all 3 of my print statements follow one right after another. I originally formatted them this way because I thought the program control would switch to the proper print statement after finding the smaller number in a comparison. But it doesn't work that way. All the assembler sees are three consecutive print statements, so it prints those.

If I only wanted one print statement to occur, I have to do some sort of program change that will either branch or jump to different code, or exit the program. Each print statement would have to end with something like this:

# print $s0 as lowest 
print_lowest_s0:
li  $v0, 1
la  $a0, ($s0)               # loads low number from comparison from $s0
syscall                      # prints low number
j   hi_int_message           # changes program control to another label

I've since changed my conditional logic, so I can't be 100% sure that what's listed in my question above is the correct logic. Here's what my logic looks like now:

# compare $s0 < $s1 
slt $t0, $s0, $s1           # if $s0 < $s1
beq $t0, 0, compare_s1_s2     # else: $t0 == 0, branch to compare $s1 < $s2 label
slt $t1, $s0, $s2           # true: compare if $s0 < $s2
beq $t1, 0, print_lowest_s2  # else: $t1 == 0, $s2 == lowest; branch to label 
j   print_lowest_s0          # true:  $s0 == lowest; jump to $s0 print label

However, the main point of this question was to stop printing everything. Hope this can help someone later!

Bobemius
  • 21
  • 4
  • Note that it's not "the assembler" that's relevant for execution falling through labels, it's "the CPU". The assembler just turns source text into binary machine code. (And labels are just ways to refer to an address; there's nothing in the machine code that indicates that there's a label here.) It's the CPU that always executes the next instructions at the following address, unless the last instruction was a jump, or a branch whose condition was true. – Peter Cordes Nov 11 '21 at 18:56