# Computing a mathematical function in MIPS assembly

This code computes the function (3x^2-4x+16) / (5x^2+2x-4). I ran the program and it works, but I am fairly new to assembly language and am not quite sure how to make the most efficient use of the registers. Does this look ok or is there a better way to do it?

.text
.globl  main

main:
ori      $8,$0, 3         #put x into $8 ori$9, $0, 3 #puts 3 into$9
ori      $10,$0,  4       #puts 4 into $10 ori$11, $0, 16 #puts 16 into$11

mult     $8,$8            #Squares x
mflo     $13 #$13 = x^2
mult     $9,$13           #Computes 3x^2
mflo     $14 #$14 = 3x^2
mult     $10,$8           # lo = 4x
mflo     $15 #$9 = 4x
sub      $16,$14,  $15 #$16 = 3x^2 -4x
add      $17,$16,  $11 #$17 = 3x^2 - 4x + 16

ori      $8,$0, 1         #put x into $8 ori$9, $0, 5 #puts 5 into$9
ori      $10,$0,  2       # put 2 into $10 ori$11, $0, 4 # puts 4 into$11

mult     $8,$8            #Squares x
mflo     $13 #$13 = x^2
mult     $9,$13           #Computes 5x^2
mflo     $14 #$14 = 5x^2
mult     $10,$8           # lo = 2x
mflo     $15 #$9 = 2x
add      $16,$14,  $15 #$16 = 5x^2 +4x
sub      $18,$16,  $11 #$17 = 5x^2 + 2x - 4

div      $17,$18          #divides 2 functions
mflo     $8 #quotient mfhi$9                #remainder
## End of file

• I won't provide you any assembly advice but would it be relevant to compile some simple C/C++ code and check the corresponding assembly code. Here's my attempt : int main(int x,char *a){return (3*xx-4*x+16)/(5*x*2+2*x-4);}. This is stupid code but I wanted to keep it simple. (You can check the assembly output with gcc.godbolt.org ) Commented Feb 28, 2013 at 0:25
• use $zero,$s... and $t... for registers. makes code more readable and robust. en.wikipedia.org/wiki/MIPS_architecture#Compiler_register_usage Commented Feb 28, 2013 at 7:44 • As long as you do not do load or store, what difference does it make if you use 7 temp registers or 8? Commented Feb 28, 2013 at 7:48 ## 1 Answer There are multiple issues: first, try to make the program work: These two lines are contradictory ori$8, $0, 3 #put x into$8
ori      $8,$0, 1         #put x into $8  Perhaps the real idea is to move a function parameter to$8.

The second thing is redundant calculation: Instead of squaring x twice, you should be able to

mul $8,$8
mflo $13 mflo$14


To catch the result in two registers.

There's no need to reserve registers for all the immediates, as one can at least add the last coefficients 16 and (-4) with

addi $x,$x, 16


Multiplications with small constants are also often better executed with a series of shifts and adds. Especially here x*4 equals x<<2 and x*2 == x+x, which leads to one less instruction for both operations.