HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

FizzBuzz in MIPS, unneccessary branches

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
branchesmipsunneccessaryfizzbuzz

Problem

I'm just starting out in MIPS (as is evident by the fact that I'm writing a FizzBuzz program), and my program runs fine and gives the desired output, but I feel like there is a way to do it without as many branches.

.data

    fstring:    .asciiz     "Fizz\n"
    bstring:    .asciiz     "Buzz\n"
    hstring:    .asciiz     "FizzBuzz\n"

.text

.globl main

main:
    li  $t0, 0

loop:
    bgt     $t0, 99, exit
    add     $t0, $t0, 1
    rem     $t1, $t0, 15
    rem     $t2, $t0, 3
    rem     $t3, $t0, 5
    beq     $t1, 0, fizzbuzz
    beq     $t2, 0, fizz
    beq     $t3, 0, buzz
    li      $v0, 1
    move    $a0, $t0
    syscall
    move    $t0, $a0
    li      $a0, 10
    li      $v0, 11
    syscall
    b       loop

fizzbuzz:
    la      $a0, hstring
    li      $v0, 4
    syscall
    b       loop

fizz:
    la      $a0, fstring
    li      $v0, 4
    syscall
    b       loop

buzz:
    la      $a0, bstring
    li      $v0, 4
    syscall
    b       loop

exit:
    li      $v0, 10
    syscall


Is there a way to sure up this program or is it relatively concise for what it's supposed to do?

Solution

Your code looks clean. Fizzbuzz is a very simple program and the most frequent reasons people get it wrong is because they go for optimizations that do not exist, rather than focusing on solving a rather simple problem.

Anything you do to optimize away those 3 branch statements is just calling for potential bugs down the line. However, in the spirit of codereview, I will give a suggestion:
DRY (Don't Repeat Yourself)

Two repetitions I noticed.

  • Printing a string (all the li $v0, 4)



  • Printing a new line.



These can be done away with by coordinating between branching and jump instructions i.e. function calls.

.data

    fstring:    .asciiz     "Fizz\n"
    bstring:    .asciiz     "Buzz\n"
    hstring:    .asciiz     "FizzBuzz\n"
    nl:         .asciiz     "\n"

.text

.globl main

main:
    li  $s0, 0

loop:
    bgt     $s0, 99, exit
    addi    $s0, $s0, 1
    move    $a0, $s0       # the function takes input with registers $a0 to $a3
    jal     check_fizzbuzz # call the function
    move    $a0, $v0       # the function returns a string in register $v0, so move it to $a0 so that it can be printed
    li      $v0, 4
    syscall                # print the string
    b loop

check_fizzbuzz:
    la      $v0, hstring
    rem     $t1, $a0, 15
    beq     $t1, 0, return_fizzbuzzz
    
    la      $v0, fstring
    rem     $t1, $a0, 3
    beq     $t1, 0, return_fizzbuzzz

    la      $v0, bstring
    rem     $t1, $a0, 5
    beq     $t1, 0, return_fizzbuzz

    li      $v0, 1
    syscall
    la      $v0, nl

return_fizzbuzz:
    jr $ra

exit:
    li      $v0, 10
    syscall

Code Snippets

.data

    fstring:    .asciiz     "Fizz\n"
    bstring:    .asciiz     "Buzz\n"
    hstring:    .asciiz     "FizzBuzz\n"
    nl:         .asciiz     "\n"

.text

.globl main

main:
    li  $s0, 0

loop:
    bgt     $s0, 99, exit
    addi    $s0, $s0, 1
    move    $a0, $s0       # the function takes input with registers $a0 to $a3
    jal     check_fizzbuzz # call the function
    move    $a0, $v0       # the function returns a string in register $v0, so move it to $a0 so that it can be printed
    li      $v0, 4
    syscall                # print the string
    b loop

check_fizzbuzz:
    la      $v0, hstring
    rem     $t1, $a0, 15
    beq     $t1, 0, return_fizzbuzzz
    
    la      $v0, fstring
    rem     $t1, $a0, 3
    beq     $t1, 0, return_fizzbuzzz

    la      $v0, bstring
    rem     $t1, $a0, 5
    beq     $t1, 0, return_fizzbuzz

    li      $v0, 1
    syscall
    la      $v0, nl

return_fizzbuzz:
    jr $ra

exit:
    li      $v0, 10
    syscall

Context

StackExchange Code Review Q#149698, answer score: 3

Revisions (0)

No revisions yet.