This is just the beginning. The whole function is going to be a whole lot complicated and lengthy (with a dozen switch statements). In the meanwhile, I came up with this code to find an approximate square root (no fractions/decimals) of 3 and 4 digit number. How would you guys improve this code.
#square root of three and four digit numbers(CASE 1)
li $t1,645
li $t7,645 #the original value to be used throughout the code
li $t2,10
li $t4,1
li $t5,10
li $s0,1
#Evaluating the remainder
div $t1,$t2
mfhi $t6 #mod value
#Getting a number whose square is less or equal to the mod value
square:
mul $s2,$s0,$s0
sub $s1,$t6,$s2
addi $s0,$s0,1
bgt $s1,1,square
addi $s0,$s0,-1 #s0 contains the first digit of the square root
numberOfDigits:
div $t1,$t2
mflo $t3 #quotient
mul $t4,$t4,$t5
move $t1,$t3
blt $t3,$t2,output
b numberOfDigits
output:
mul $s3,$t4,$s2 #s3 should give the multiple
sub $s4,$t7,$s3 #s4 should contain 245
#CASE 1
#the given number is 3 digits (a three digit number can only have a two digit square root)
#Reusing previous registers
mul $s2,$s2,10
li $t3,0
multiple:
mul $t4,$s2,$t3
bgt $t4,$s4,exitFunction
addi $s2,$s2,1
addi $t3,$t3,1
b multiple
exitFunction:
addi $t3,$t3,-1
li $v0,1
move $a0,$s0
syscall
li $v0,1
move $a0,$t3
syscall
Complicated and hard to thoroughly test are always wining strategies with assembler.
Some comments, and an explanation of the algorithm would help the readability.
As I pointed to in your previous post, there are efficient ways to avoid expensive multiplication, or divisions in this computation. In the M4K they cost 32 or 25 cycles as I recall.