Monday, May 11, 2020

MIPS print_integer subroutine

This is a sample MIPS program that loops 10 times and with each iteration it calls the 'print_integer(int num)' subroutine. The 'print_integer(int num)' subroutine prints "The number is n", where n is the argument passed in $a0. Care has been taken to preserve local variables. The code is fully documented.

Launch EzMIPSthe MIPS assembler simulator, copy the following MIPS code and paste it into EzMIPS. Assemble, Run.

# ---------------------------------------------------------------- #

.data
count:         .word   10
szTheNumberIs: .asciiz "The number is "
szLF:          .asciiz "\n"

# ---------------------------------------------------------------- #
.text

# ................................................................ #

    jal main               # after executing, $ra will be equal to 0x00400004
    
    li $v0, 10
    syscall                # exit program

# ................................................................ #

main:

    # ............. Adjust stack ($sp = 0x7fffefdc) .............. #
    addiu $sp, $sp, -32
    # ............. Adjust stack ($sp = 0x7fffefdc) .............. #

    sw $ra, 24($sp)        # (0x7fffefdc + 24) = (0x7fffeff4) = 0x00400004
    sw $fp, 16($sp)        # save old frame pointer, (0x7fffefec) = $fp = 0
    addiu $fp, $sp, 28     # load new frame pointer
                           # ie $fp = 0x7fffefdc + 28 = 0x7fffeff8

    # ............................................................ #
    la $t0, count
    lw $t1, 0($t0)         # $t1 = 10
    li $t0, 0              # init index to 0


   loop:
    sw $t0, 12($sp)        # save caller saved registers (0x7fffefe8) = $t0
                           # 0, 1, 2, 3, ... , 9
    sw $t1, 8($sp)         # (0x7fffefe4) = $t1 = 10 = 0xa

    move $a0, $t0          # setup parameter for function call
                           # ie $a0 = 0, 1, 2, 3, ... , 9

    jal print_integer      # call subroutine

    # restore caller saved values
    lw $t1, 8($sp)         # ie $t1 = (0x7fffefe4) = 10 = 0xa
    lw $t0, 12($sp)        # ie $t0 = (0x7fffefe8) = 0, 1, 2, 3, ... , 9



    addiu $t0, $t0, 1      # increment index; ($t0++;)
    blt $t0, $t1, loop     # loop if $t0 < 10

    # ............................................................ #

    lw $fp, 16($sp)        # restore frame pointer
    lw $ra, 24($sp)        # restore return address

    # ............ Restore stack ($sp = 0x7fffeffc) .............. #
    addiu $sp, $sp, 32     # restore stack pointer
    # ............. Restore stack ($sp = 0x7fffeffc) ............. #

    jr $ra

# ................................................................ #

print_integer:

    # ............. Adjust stack ($sp = 0x7fffefbc) .............. #
    addiu $sp, $sp, -32
    # ............. Adjust stack ($sp = 0x7fffefbc) .............. #

    sw $fp, 16($sp)
    sw $s0, 12($sp)
    addiu $fp, $sp, 28

    move $s0, $a0          # store argument in temp variable

    li $v0, 4
    la $a0, szTheNumberIs  # point to "This number is "
    syscall                # print string syscall

    li $v0, 1
    move $a0, $s0          # restore argument $a0
    syscall                # print integer syscall

    li $v0, 4
    la  $a0, szLF          # point to "\n"
    syscall                # print string syscall

    lw $s0, 12($sp)
    lw $fp, 16($sp)

    # ............. Restore stack ($sp = 0x7fffefdc) ............. #
    addiu $sp, $sp, 32
    # ............. Restore stack ($sp = 0x7fffefdc) ............. #


    jr $ra                 # jump to return address

# ---------------------------------------------------------------- #

Please let me know of any suggestions or bugs regarding the code above.

Regards,

Antonis

No comments:

Post a Comment