HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

Computing a mathematical function in MIPS assembly

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
mipsfunctionassemblymathematicalcomputing

Problem

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

Solution

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 x4 equals x<<2 and x2 == x+x, which leads to one less instruction for both operations.

Code Snippets

ori      $8, $0, 3         #put x into $8
ori      $8, $0, 1         #put x into $8
mul $8, $8
mflo $13
mflo $14
addi $x, $x, 16

Context

StackExchange Code Review Q#23245, answer score: 3

Revisions (0)

No revisions yet.