assemblyx86mipsmars-simulator

Clarification about a MIPS program that asks to Provide whether a month has 28/29, 30 or 31 days


Due the lack of sources I could get my hands on, it seemed strange to me that nobody posted a program as a solution for this question on the internet in MIPS (unless I'm that bad at surfing the internet). I require clarificatoin about whether my program can be written in a more efficient and optimized way rather than just spamming Labels&Branches!!

.data
    msg : .asciiz "Give the month: "
    msg1 : .asciiz "This month contains 31 Days."
    msg2 : .asciiz "This month contains 30 Days."
    msg3 : .asciiz "This month contains 28/29 Days."
.text
.globl main
main:
    li $v0,4
    la $a0,msg
    syscall
    
    li $v0,5
    syscall
    move $t0,$v0   #t0 contains given month
    
    li $t7,7
    li $t2,2       
    li $t1,0
    
    div $t0,$t2
    mfhi $t3
    mflo $t4
    
    bgt $t0,$t7,etiq3
    beq $t0,$t2,etiq2
    beqz  $t3,etiq1
    bgtz $t3,etiq
    
    
    etiq:
    li $v0,1
    addi $a0,$s1,0
    syscall
    li $v0,4
    la $a0,msg1
    syscall
    j exit 
    
    etiq1:
    li $v0,1
    addi $a0,$s0,0
    syscall
    li $v0,4
    la $a0,msg2
    syscall
    j exit
    
    etiq2:
    li $v0,1
    addi $a0,$s0,0
    syscall
    li $v0,4
    la $a0,msg3
    syscall
    j exit
    
    etiq3:
    beqz $t3,etiq
    bgtz $t3,etiq1
    
    exit:
    li $v0,10
    syscall

Solution

  • Your code isn't well commented so hard to follow. Especially why you are printing $s0 and $s1 neither of which seem to be initialized.

    As for an optimized solution, a possibility would be to use a bitmap (2 bits per month):

    .data
        msg : .asciiz "Give the month: "
        msg1 : .asciiz "This month contains 31 Days."
        msg2 : .asciiz "This month contains 30 Days."
        msg3 : .asciiz "This month contains 28/29 Days."
        table: .word msg3, msg2, msg1
    .text
    .globl main
    main:
        li $v0,4
        la $a0,msg
        syscall
    
        li $v0,5
        syscall
    
        # 00 = 28/29, 01 = 30, 10 = 31
        li $a0, 0x099a6620  # 1001 1001 1010 0110 0110 0010 0000
        sll $v0, $v0, 1     # 2 bits per month
        srlv $a0, $a0, $v0  # shift the bitmap
        andi $a0, $a0, 0x0c # keep the 2 bits
        lw $a0, table($a0)
        li $v0,4
        syscall
        li $v0,10
        syscall
    

    You could of course just put the message pointers into a table with 12 entries as well for somewhat simpler code at the expense of more memory.