Using the andi 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-9`  | temporary | any     | used for temporary storage                       |

.globl is_leap_year

is_leap_year:
        li      $v0, 0

        andi    $t0, $a0, 3
        bnez    $t0, end

        li      $t0, 100
        div     $a0, $t0
        mfhi    $t0
        bnez    $t0, set_leap

        mflo    $t0
        andi    $t0, $t0, 3
        bnez    $t0, end

set_leap:
        li      $v0, 1
end:
        jr      $ra

Equivalent C code:

#include <stdlib.h>

int is_leap_year(int year) {
    if ((year & 3) != 0) {
        return 0;
    }

    div_t by_100 = div(year, 100);
    return by_100.rem != 0 || (by_100.quot & 3) == 0;
}

This approach uses the andi instruction to determine if the year is divisible by 4 by relying on the fact that if a number is divisible by 4, its two least significant bits will be zero.

To determine if the year is divisible by 100, we then use div combined with mfhi to get the remainder. Finally, if we need to check if the year is divisible by 400, we use another trick: calling div left the quotient of the division by 100 in the lo register. Thus, we can fetch that quotient using mflo and then re-use the same trick as before to determine if that quotient is divisible by 4 (making the year divisible by 400).

6th Nov 2024 · Found it useful?