我必须在MIPS程序集中创建一个程序,它将双精度浮点数除以单精度数(使用标准IEEE 754)而不使用浮点指针单元。我唯一无法理解的是如何处理两个数字的尾数来计算除法,这里是代码,除法的部分是在标签divis中:(在$ t2和$ t3我有两个部分的双精度数尾数,$ t6单精度的尾数)......
.data
res: .asciiz "result is="
neg_res: .asciiz "result is= - "
choice: .asciiz "\nMake your choice:\n1)execute\n2)exit\n"
wrong: .asciiz "Inserted value not correct!!"
first: .asciiz "insert the first number"
n: .asciiz "\n"
second: .asciiz "insert the second number"
divz: .asciiz "can't divide for 0"
.text
main:
la $a0, choice
li $v0, 4
syscall #Print first part
li $v0, 5
syscall #input choice
move $t7, $v0
beq $t7,2, end #Control=2
blt $t7,1, err #control<1
bgt $t7,2, err #control>2
getdoub:
la $a0, first
li $v0, 4
syscall #Message for input numerator
li $v0, 7
syscall
mov.d $f4, $f0 #input double numerator
getfloat:
la $a0, second
li $v0, 4
syscall
li $v0, 6
syscall
mov.s $f6, $f0 #input float denominator
li $t1,1
mtc1 $t1,$f8
cvt.s.w $f8,$f8
c.eq.s $f6,$f8 #Control if the denominator is =1
bc1t print_dou #print double
li $t0,0
mtc1 $t0,$f8
cvt.s.w $f8,$f8
c.eq.s $f6,$f8 #Control if denominator è =0
bc1t errz #print error
# fin qua tutto bene
sign_d:
cvt.d.s $f8,$f8 #convert from single to double to avoid errors in compare
c.lt.d $f4, $f8 #control sign of double
bc1t minus_d #if c1 is true (that means $f4<$f8) jump to minus_d
b plus_d #otherwise plus_d
minus_d:
li $t0, 1 #negative sign
plus_d:
li $t0, 0 #positive sign
extr_double:
mfc1.d $t2,$f4 #in $t2 I've sign, exponent and 20 bit of mantissa in t3, 32 bit of mantissa
li $t6, 2146435072 #Mask for 11 bit of exponent
and $t1,$t2,$t6 #in $t1 Exponent
li $t6, 1048575 #mask for 20 bit of mantissa
and $t2, $t2,$t6
add $t2,$t2, 2097152 #in t2 I've mantissa 1 and in t3 ho la mantissa 2 automatically
# fin qui logicamente ci siamo... I've taken sign, exponent, mantissa 1 and 2
sign_s:
cvt.s.d $f8, $f8 #convert $f8 from double to single
c.lt.s $f6, $f8 #same control made for numerator
bc1t minus_s
b plus_s
minus_s:
li $t4, 1
b extr_sing
plus_s:
li $t4,0
# t4 sign
extr_sing:
mfc1 $t6,$f6
li $t7, 2139095040 # 8 bit of exponent a 1
and $t5,$t6,$t7 # in $t5 I've exponent
li $t7, 8388607 #mask for 23 bit
and $t6, $t6,$t7
add $t6, $t6, 16777216 # in $t6 I've mantissa
sign:
xor $t0,$t0,$t4 #Sign of result
beqz $t0, print_res
b p_neg_res
exp:
sub $t5,$t5, 1023 #taking real exponent
sub $t1,$t1, 127 #taking real exponent
sub $t1,$t1,$t5 #in $t1 I've the exponent of the final number
add $t1,$t1, 1023 #adding bias (the final number will be a double)
sll $t1,$t1,20 #shifting so when I add $t2 (the first part of mantissa) I have the number in the right position
divis:
div $t3,$t3,$t6 #first part of division (32 bit of mantissa)
div $t2,$t2,$t6 #second part of division (20 bit of mantissa)
#HUGE QUESTION MARK
add $t2, $t1,$t2 #Adding exponent and mantissa, in this way in $t2 I have all the information
mtc1.d $t2,$f4 #$t2 & $t3 are moved in $f4 & $f5 so I have a double number in $f4...I Hope
b print_dou
print_res: #Print positive result
la $a0, res
li $v0, 4
syscall
b divis
p_neg_res: #print negative result
la $a0, neg_res
li $v0, 4
syscall
b divis
err: #Error in the choice
la $a0, wrong
li $v0, 4
syscall
b main
end: #End program
li $v0,10
syscall
errz: #Error dividing by 0
la $a0, divz
li $v0, 4
syscall
b main
print_dou: #Print the number!!
mov.d $f12,$f4
li $v0,3
syscall
b main