2015-04-25 85 views
-2

我必須在MIPS彙編中編寫一個程序,它將雙精度浮點數除以單精度數(使用標準IEEE 754),而不使用浮點指針單元。我唯一不能理解的是如何處理這兩個數字的尾數來計算分割。如何遍歷個別位?在沒有FPU的MIPS彙編中將單精度(IEEE 754)分爲雙精度

.data 

res: .asciiz "Result is: " 
neg_res:.asciiz "Result is: - " 
choice: .asciiz "\nMake your choice:\n1. Execute\n2. Exit\n" 
wrong: .asciiz "Inserted value is wrong! Please try one more time." 
first: .asciiz "Insert the first number: " 
n:  .asciiz "\n" 
second: .asciiz "Insert the second number: " 
divz: .asciiz "Can't divide for 0! Please try one more time." 

.text 

main: 
    la $a0, choice 
    li $v0, 4 
    syscall     # Print menu 

    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 

    c.eq.d $f4, $f30 
    bc1t print_dou  # Print result if numerator is = 0 

getfloat: 
    la $a0, second 
    li $v0, 4 
    syscall    # Message for input denominator 

    li $v0, 6 
    syscall 
    mov.s $f6, $f0  # Input float denominator 

    c.eq.s $f6, $f30 
    bc1t errz   # Print error if denominator is = 0 

    sign_d: 
    cvt.d.s $f6, $f6  # Convert from single to double to avoid errors in compare 

    c.lt.d $f4, $f6   # 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   # Iin $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 


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: # Sign of result 
    xor  $t0, $t0, $t4  
    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 of 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, $f30 # bylo #f4 
    li $v0, 3 
    syscall 
    b main 
+1

發佈你一直在努力的代碼,直到現在 –

+0

迭代位是迄今爲止這個問題最容易的部分.. – harold

+0

我剛剛發佈了一些代碼。請給我一些提示如何開始...我很沮喪... – nytmrae55

回答

1

當計算結果$t1的指數,你有正確的想法,但雖然1.0/1.5f1.5/1.0f各自的操作數相同,則結果的指數相差一個。在第一種情況下,您可以做的是,在減少$t1的同時,將分子左側的有效位移動1。你需要在提取兩個有效位之後設置各自的隱含有效位(顯然,在第一段中建議的調整之前設置先前隱含的位,否則將變得複雜)。

之後,您將實施一個部門。以下說明做實現53位除法:

div  $t3, $t3, $t6  # First part of division (32 bit of mantissa) 
div  $t2, $t2, $t6  # Second part of division (20 bit of mantissa) 

首先,他們忘了隱位,和第二,這只是不是它是如何工作。

您以1xxxxxxxxx(52或53位)xxxxxxxxxxx和1yyyyy(23位)yyyyy開頭。在第一段中,您確定分子的有效位數大於分母的位數,因此第一位數字計算爲1(它將隱式存儲在最終結果中)。接下來你需要從前者中減去後者。如果你還沒有在步驟1中轉移,減法是這樣的:

 
1xxxxxxxxxxx 
-1yyyyyyy 
_____________ 
zzzzzzzzzzzz 

如果你在步驟1中已經改變,它看起來像這樣:

 
1xxxxxxxxxxx 
- 1yyyyyyy 
_____________ 
zzzzzzzzzzzz 

移由一個離開的結果,並將新值與1yyyyyyyy進行比較。如果新值大於或等於1yyyyyyy,則下一個數字爲1,必須再次減去1yyyyyyy。如果它較低,則下一個數字是0(並且不減)。

在這兩種情況下,再次左移並計算下一個數字。 等等......

+0

更好的方式來做有效數除法算法是讓他們在寄存器或內存? – nytmrae55