Search code examples
assemblymipsmips32mars-simulator

MIPS-Assembly: How to 'define' subroutine for later use


There are tons of great examples on how to properly follow MIPS function calling conventions. However, I'm getting stuck on how to use a function only when 'called'. The following will print 51 (using MARS):

.data
strproc: .asciiz "procedure example"
strnl: .ascii "\n"

.text
printnl: li $v0, 1
li $a0, 5
syscall

#jal printnl

li $v0, 1
li $a0, 1
syscall

However, I'd really like to be able to only execute the instructions associated with the printnl label when jumped and linked to (when 'called'). Is this feasible in MIPS? Feel free to criticize my design inclinations as part of your answer. I'm not sure how I should go about writing a simple assembly program who may have need of a lot of repeated instructions.

I did try this (but it doesn't assemble):

.data
strproc: .asciiz "procedure example"
strnl: .ascii "\n"

printnl: li $v0, 1
li $a0, 5
syscall

.text
li $v0, 1
li $a0, 1
syscall
jal printnl

Solution

  • Execution progresses from one instruction to the next unless you redirect it. In SPIM I guess execution begins at the beginning of the text segment and ends when you invoke an exit system call (system call #10). If you put your routine after an exit system call, a function return, or any other unconditional branch, control never reaches it unless you call it explicitly. For example:

            .data
    strproc:.asciiz "procedure example"
    strnl:  .ascii "\n"
    
            .text
            # entry point
            li $v0, 1
            li $a0, 1
            syscall     # print integer 1
    
            jal println # call println
    
            li $v0, 10
            syscall     # exit program
    
    printnl:li $v0, 1
            li $a0, 5
            syscall     # print integer 5
            jr $ra      # return from function