2015-01-09 6 views
2

MIPS 프로젝트에 문제가 있습니다. 작업은 부동 소수점 단위를 사용하지 않고 binary64 (double) 숫자에 부호있는 정수를 곱하는 것입니다. 거의 잘 작동하지만 일부 숫자의 경우 오류가 발생합니다 (예 : float-123456789123456, int - 1). 오류로 인해 나는 7 번째 숫자 이후에 내 결과가 적절한 것으로 보이는 것을 의미합니다. 난 프로 시저 (어쩌면 mantissa2의 $ 높은 및 mantissa2의 $ 낮은 추가하는 과정에서) 약간의 비트 전송에 문제가있을 수 있습니다 용의자. 나는 그것을 바로 잡으려고 노력했지만, 지금까지 나는 그것을 어떻게하는지 모른다. 가능한 경우 내 코드를 확인하고 수정하십시오.MIPS - IEEE binary64 (double) 및 부호있는 정수 곱셈

  .data 
text1: .asciiz "Enter double: " 
text2: .asciiz "Enter integer: " 
text3: .asciiz "Result: " 
quest: .asciiz "\nIf you want to multiply enter 1, otherwise enter 0: " 

num1a: .word  0   #multiplicand and result(sign exponent and first part of mantissa) 
num1b: .word  0   #second part of the multiplicand and result(remaining part of mantissa) 
num2: .word  0   #integer 

    .text 
    .globl input  
input: 
    #print "Enter double: " 
    la $a0, text1 
    li $v0, 4 
    syscall 
    # saving input double into num1 
    li $v0, 7 
    syscall     
    swc1 $f0, num1b 
    swc1 $f1, num1a 
    #print "Enter integer: " 
    la $a0, text2 
    li $v0, 4 
    syscall 
    # saving input int into num2 
    li $v0, 5 
    syscall 
    sw $v0, num2 
    # loading data to registers 
    lw $t0, num1a 
    lw $t1, num1b 
    lw $t2, num2 
#########################################################sign 
sign:  
    move $t3, $t0 
    andi $t3, $t3, 0x80000000 #preserve sign, zero the rest 
    bgez $t2, extract  #if less than zero we change the final sign and negate the value of integer 
    xori $t3, $t3, 0x80000000 #multiply signs (if integer is negative, then the sign is equal to $s0) 
    neg $t2, $t2  #absolute value of int 
extract:  
################################################checking for zero 
    or $t5, $t0, $t1  #if both part of double are equal to zero we skip all the calculation 
    beqz $t5, result_zero 
    beqz $t2, result_zero 
###############################sign, exponent and mantissa 
    move $t7, $t0  
    andi $t7, $t7, 0x7FF00000 #extracting exponent to $t7 
    move $t8, $t0 
    andi $t8, $t8, 0x000FFFFF #extracting first part of mantissa 
    ori  $t8, $t8, 0x00100000 #adding prefix one to mantissa 
    #remaining mantissa stays in register $t1 
######################################################### 
multiply: 
    ########################multiplying mantissa part 1 
    multu $t8, $t2  #multiply mantissa1 by integer 
    mflo $t8   #low part of multiplication to $t8 
    mfhi $s1   #high part of multiplication to $s1 
    ########################multiplying mantissa part 2 
    multu $t1, $t2  #mantissa part 2 multiplication 
    mflo $t1   #low part to $t1 
    mfhi $t0   #with overflow going to $t0 
    ########################partial accumulation 
    addu $t8, $t8, $t0  #adding the high part of mantissa2 to result of low part of mantissa1 
    bgeu $t8, $t0, skip_add #if the result is less than any element we add 1 to mantissa1 high 
    addiu $s1, $s1, 1 
    ###### 
skip_add: 
    bnez $s1, shift 
    bltu $t8, 0x00200000, result  
shift: #else we shift 3 parts of mantissa and increment the the exponent 
    ###extracting least significant bit of high mantissa1 
    sll $s2, $s1, 31  #copying least significant beat of $s1 to most significant bit in $s2 
    sll $t9, $t8, 31  #copying least significant beat of $s8 to most significant bit in $t9 
    ###### 
    srl $s1, $s1, 1  #shifting right mantisa part1 high 
    srl $t8, $t8, 1  #shifting right mantisa part1 low 
    or $t8, $t8, $s2  #copying least significant bit from mantissa1- high to most significant bit of mantissa1 low 
    srl $t1, $t1, 1  #shifting right mantisa part2 
    or $t1, $t1, $t9  #copying least significant bit from mantissa1 to most significant bit of mantissa2 
    ###### 
    addiu $t7, $t7, 0x00100000 #increment exponent by one 
    ###### 
    bnez $s1, shift  #if mantissa1 high is greater than zero we continue 
    bgeu $t8, 0x00200000, shift #if mantissa1 low exceeds final mantissa space 
result: 
    andi $t8, $t8, 0x000FFFFF #preserve mantissa, zero the rest(cut the prefix - one) 
    move $t0, $t3  #copy propoer sign 
    or $t0, $t0, $t7  #add exponent 
    or $t0, $t0, $t8  #add mantissa part1 
    b output 
result_zero: 
    li $t0, 0 
    li $t1, 0 
output: 
    sw $t0, num1a 
    sw $t1, num1b 
    #print "Result: " 
    la $a0, text3 
    li $v0, 4 
    syscall 
    lwc1 $f12, num1b 
    lwc1 $f13, num1a 
    #print double - the result 
    li $v0, 3 
    syscall 
question: 
    la $a0, quest   #Do you want to enter new numbers or finish? 
    li $v0, 4 
    syscall 
    li $v0, 5    #reads the answer (integer) 
    syscall 
    beq $v0, 1, input   #if input =1, continue, if 0 finish, otherwise ask again 
    beqz $v0, fin 
    b question 
fin: 
    li $v0, 10    #exit 
    syscall 

나는 문제가 (곱하기)이 절에있을 것 같아요 :

addu $t8, $t8, $t0  #adding the high part of mantissa2 to result of low part of mantissa1 
bgeu $t8, $t0, skip_add #if the result is less than any element we add 1 to mantissa1 high 
#addiu $s1, $s1, 1 
    ###### 
skip_add: 
    bnez $s1, shift 
    bltu $t8, 0x00200000, result 

추가하는 프로세스는이 수행 될 수 있습니다. 나는 명령문 (addiu)에있는 명령으로 처리하려고 시도했다. 이것은 두 개의 부호없는 숫자를 더한 결과가 그들 중 하나보다 작 으면 캐리를 얻고 가장 중요한 $ s1을 등록하기 위해 1을 더해야한다는 것을 의미한다. 가수의 일부. 도움이 안돼. 제 생각에는

+0

당신은 당신이 발생하는 것을 오류에 대한 정보를 제공 할 수 있다면 당신은 아마 코드의 일부 조항에 문제를 드릴 다운 할 수있는 경우이 과정은 쉬울 것 . MIPS 어셈블러와 IEEE 부동 소수점을 알고있는 사람들이 거의 없으므로, 여러분이 질문에 제공하는 정보가 많을수록 좋습니다. – dho

+0

게시물을 수정했습니다. 나는 이제 내 생각을 이해하기 쉽게 바란다. – Kornel

+0

감사하게도 문제가 해결되었습니다. 실제로 곱셈 섹션에 실수가있었습니다. 그러나 문제는 다기능을 사용함에있었습니다. 이제는 정확하고 효과적입니다. 나는 그것이 미래에 누군가를 도울 것이라고 희망한다. – Kornel

답변

1

이 올바른 코드 :

.data 
text1: .asciiz "Enter double: " 
text2: .asciiz "Enter integer: " 
text3: .asciiz "Result: " 
quest: .asciiz "\nIf you want to multiply enter 1, otherwise enter 0: " 

num1a: .word  0   #multiplicand and result(sign exponent and first part of mantissa) 
num1b: .word  0   #second part of the multiplicand and result(remaining part of mantissa) 
num2: .word  0   #integer 

    .text 
    .globl input  
input: 
    #print "Enter double: " 
    la $a0, text1 
    li $v0, 4 
    syscall 
    # saving input double into num1 
    li $v0, 7 
    syscall     
    swc1 $f0, num1b 
    swc1 $f1, num1a 
    #print "Enter integer: " 
    la $a0, text2 
    li $v0, 4 
    syscall 
    # saving input int into num2 
    li $v0, 5 
    syscall 
    sw $v0, num2 
    # loading data to registers 
    lw $t0, num1a 
    lw $t1, num1b 
    lw $t2, num2 
#########################################################sign 
sign:  
    move $t3, $t0 
    andi $t3, $t3, 0x80000000 #preserve sign, zero the rest 
    bgez $t2, extract  #if less than zero we change the final sign and negate the value of integer 
    xori $t3, $t3, 0x80000000 #multiply signs (if integer is negative, then the sign is equal to $s0) 
    neg $t2, $t2  #absolute value of int 
extract:  
################################################checking for zero 
    or $t5, $t0, $t1  #if both part of double are equal to zero we skip all the calculation 
    beqz $t5, result_zero 
    beqz $t2, result_zero 
###############################sign, exponent and mantissa 
    move $t7, $t0  
    andi $t7, $t7, 0x7FF00000 #extracting exponent to $t7 
    move $t8, $t0 
    andi $t8, $t8, 0x000FFFFF #extracting first part of mantissa 
    ori  $t8, $t8, 0x00100000 #adding prefix one to mantissa 
    #remaining mantissa stays in register $t1 
######################################################### 
multiply: 
    ########################multiplying mantissa part 1 
    multu $t8, $t2  #multiply mantissa1 by integer 
    mflo $t8   #low part of multiplication to $t8 
    mfhi $s1   #high part of multiplication to $s1 
    ########################multiplying mantissa part 2 
    multu $t1, $t2  #mantissa part 2 multiplication 
    mflo $t1   #low part to $t1 
    mfhi $t0   #with overflow going to $t0 
    ########################partial accumulation 
    addu $t8, $t8, $t0  #adding the high part of mantissa2 to result of low part of mantissa1 
    bgeu $t8, $t0, skip_add #if the result is less than any element we add 1 to mantissa1 high 
    addiu $s1, $s1, 1 
    ###### 
skip_add: 
    bnez $s1, shift 
    bltu $t8, 0x00200000, result  
shift: #else we shift 3 parts of mantissa and increment the the exponent 
    ###extracting least significant bit of high mantissa1 
    sll $s2, $s1, 31  #copying least significant beat of $s1 to most significant bit in $s2 
    sll $t9, $t8, 31  #copying least significant beat of $s8 to most significant bit in $t9 
    ###### 
    srl $s1, $s1, 1  #shifting right mantisa part1 high 
    srl $t8, $t8, 1  #shifting right mantisa part1 low 
    or $t8, $t8, $s2  #copying least significant bit from mantissa1- high to most significant bit of mantissa1 low 
    srl $t1, $t1, 1  #shifting right mantisa part2 
    or $t1, $t1, $t9  #copying least significant bit from mantissa1 to most significant bit of mantissa2 
    ###### 
    addiu $t7, $t7, 0x00100000 #increment exponent by one 
    ###### 
    bnez $s1, shift  #if mantissa1 high is greater than zero we continue 
    bgeu $t8, 0x00200000, shift #if mantissa1 low exceeds final mantissa space 
result: 
    andi $t8, $t8, 0x000FFFFF #preserve mantissa, zero the rest(cut the prefix - one) 
    move $t0, $t3  #copy propoer sign 
    or $t0, $t0, $t7  #add exponent 
    or $t0, $t0, $t8  #add mantissa part1 
    b output 
result_zero: 
    li $t0, 0 
    li $t1, 0 
output: 
    sw $t0, num1a 
    sw $t1, num1b 
    #print "Result: " 
    la $a0, text3 
    li $v0, 4 
    syscall 
    lwc1 $f12, num1b 
    lwc1 $f13, num1a 
    #print double - the result 
    li $v0, 3 
    syscall 
question: 
    la $a0, quest   #Do you want to enter new numbers or finish? 
    li $v0, 4 
    syscall 
    li $v0, 5    #reads the answer (integer) 
    syscall 
    beq $v0, 1, input   #if input =1, continue, if 0 finish, otherwise ask again 
    beqz $v0, fin 
    b question 
fin: 
    li $v0, 10    #exit 
    syscall