functionassemblymipsmips32mars-simulator

MIPS32 MARS - put algorithm in function


so i have a little program in mars assembly which gets the greatest common divisor:

.text
    addiu $4,$zero,49
    addiu $5,$zero,42
    add $2,$zero,$5

    beq  $4,$zero,label10
loop:   
    beq $5,$zero,label9
    
    slt $9,$5,$4
    bne  $9,$zero,if
    
    slt $10,$4,$5
    bne $10,$zero,else
    beq  $10,$zero,else##if $4 and $5 are equal.
if:
    sub $4,$4,$5
    j endif
else:
    sub $5,$5,$4
    j endif
endif:  
    j loop
label9:
    add $2,$0,$4
label10:

The result will be saved in register 2. Now my second task is, i should change my program so that my algorithm is some "function"(subprogram), where you can set arguments for register 4 and 5 and the return value in register 2. My problem now is, i dont know how to do that.


Solution

  • Here's what to do in order to turn a snippet of code into a function:

    1. Give it a label at the beginning, e.g. MyFunc.
    2. Put a return at the end: jr $ra.
    3. Make a test main that calls your function and place this at the beginning of the .text section — you want this test main to be what the simulator runs first, so it will call your function — you don't want your function first, because as it is no longer a snippet, but now a function, it should be properly invoked: by passing parameters and return address.  The main also has to properly terminate the program otherwise it will run off the edge and run the function again, but accidentally this time.
        .text
        # test main: call MyFunc
        #
        # call function, pass some parameters
        li $a0, 20          # load first arg register
        li $a1, 15          # load second arg register
        jal MyFunc          # the actual invocation 
                            # this jumps to the function, 
                            #   while also passing the return address in $ra
    
                            # here's where come back to when the function is done:
        move $a0, $v0       # move return value into $a0, so we can print it
    
        li $v0, 1           # and print
        syscall
    
        li $v0, 10          # and stop the program
        syscall
    #
    #
    #
    MyFunc:                 # start of MyFunc
        # ...               # code of function goes here
        jr $ra              # jump back to the caller by using the return address register
    

    Suggest using friendly register names instead of the simple numeric names.  (And we should never mix friendly names with the simple numeric ones in the same program.)