FizzBuzz in MIPS, unneccessary branches
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     &quot;Fizz\n&quot;
    bstring:    .asciiz     &quot;Buzz\n&quot;
    hstring:    .asciiz     &quot;FizzBuzz\n&quot;
    nl:         .asciiz     &quot;\n&quot;

.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