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 EzMIPS, the 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