Using the div instruction

Leap
Leap in MIPS Assembly
## Registers

# | Register | Usage     | Type    | Description                                           |
# | -------- | --------- | ------- | ----------------------------------------------------- |
# | `$a0`    | input     | integer | year to check                                         |
# | `$v0`    | output    | boolean | input is leap year (`0` = `false`, `1` = `true`)      |
# | `$t0`    | temporary | boolean | year is multiple of 4 (`0` = `false`, `1` = `true`)   |
# | `$t1`    | temporary | boolean | year is multiple of 100 (`0` = `false`, `1` = `true`) |
# | `$t2`    | temporary | boolean | year is multiple of 400 (`0` = `false`, `1` = `true`) |

.globl is_leap_year

is_leap_year:
        li      $t0, 4
        div     $a0, $t0
        mfhi    $t0
        seq     $t0, $t0, $zero

        li      $t1, 100
        div     $a0, $t1
        mfhi    $t1
        seq     $t1, $t1, $zero

        li      $t2, 400
        div     $a0, $t2
        mfhi    $t2
        seq     $t2, $t2, $zero

        sub     $v0, $t0, $t1
        add     $v0, $v0, $t2
        jr      $ra

Equivalent C code:

int is_leap_year(int year) {
    int is_multiple_4 = (year % 4 == 0);
    int is_multiple_100 = (year % 100 == 0);
    int is_multiple_400 = (year % 400 == 0);
    return is_multiple_4 - is_multiple_100 + is_multiple_400;
}

This approach uses the div instruction to compute the remainder of divisions. This instruction actually computes both the quotient and the remainder of the division and places them in the lo and hi registers, respectively.

However, those registers cannot be used as arguments to most instructions. Instead, in order to use their values, we need to move them from the lo or hi registers into another register using the mfhi (move from hi) or mflo (move from lo) instructions.

The seq instruction sets a register to 1 if the two values are equal, and otherwise sets the register to 0.

6th Nov 2024 · Found it useful?