2014-12-03 42 views
0

作爲一項家庭作業,我們需要使用由C程序驅動的彙編程序計算調和平均值。諧波平均收益率不正確結果

我們使用的是64位linux機器,並且需要使用64位浮點數。

我是Assembly的新手。對於任何不好的編碼做法,或者我的代碼是錯誤的,我表示歉意。


代碼的問題是結果只返回以浮點格式輸入的最後一個數字。我不知道錯誤發生在哪裏,但我相信它在addDen函數中。

作爲示例:如果要輸入數字5,6,7,8,結果將返回8.0000。

這裏是我的彙編程序代碼:

;Assembly function that computs the harmonic mean 
;of an array of 64-bit floating-point numbers. 
;Retrieves input using a C program. 
; 
;Harmonic mean is defined as Sum(n/((1/x1) + (1/x2) + ... + (1/xn))) 
; 
; expects: 
;  RDI - address of array 
;  RSI - length of the array 
; returns 
;  XMMO - the harmonic average of array's values 

global harmonicMean 

section .data 
    Zero dd 0.0 
    One dd 1.0 

section .text 
    harmonicMean: 
     push rbp 
     mov rbp, rsp     ;C prologue 

     movss xmm10, [Zero]  ;Holds tally of denominator 
     cvtsi2ss xmm0, rsi  ;Take length and put it into xmm0 register 

     .whileLoop: 
      cmp rsi, 0     ;Is the length of array 0? 
      je .endwhile 
      call addDen     ;Compute a denominator value and add it to sum 
      add rdi, 4     ;Add size of float to address 
      dec rsi       ;Decrease the length 
      jmp .whileLoop 
     .endwhile: 

     divss xmm0, xmm10 

     leave 
     ret 


    ;Calculates a number in the denominator 
    addDen: 
     push rdi 
     movss xmm8, [One] 
     movss xmm9, [rdi] 
     divss xmm8, xmm9 
     addss xmm10, xmm8 
     pop rdi 
     ret 

爲了重建邏輯錯誤,我也包括我的驅動程序:

/* 
* Harmonic Mean Driver 
* Tyler Weaver 
* 03-12-2014 
*/ 
#include<stdio.h> 

#define ARRAYSIZE 4 

double harmonicMean(double *, unsigned); 

int main(int argc, char **argv) { 
    int i; 
    double ary[ARRAYSIZE]; 
    double hm; 

    printf("Enter %d f.p. values: ", ARRAYSIZE); 

    for (i = 0; i < ARRAYSIZE; i++) { 
     scanf(" %lf", &ary[i]); 
    } 

    hm = harmonicMean(ary, ARRAYSIZE); 
    printf("asm: harmonic mean is %lf\n", hm); 

    return 0; 
} 

任何幫助將是非常感激!

+1

「double *」和「unsigned」的大小與「RDI」和「RSI」的大小相同嗎?建議'printf(「%zu%zu \ n」,sizeof(double *),sizeof(unsigned));'驗證。 – chux 2014-12-03 22:55:46

+0

它們應該分別爲4個字節。我們被告知使用double和unsigned爲驅動程序。在分配細節。我是Assembly的新手,所以我不知道這是否溢出寄存器。該數組將會更長,但RDI寄存器應該只保存陣列的前4個字節。 – 2014-12-03 22:59:40

+0

同意_should_每個都是4個字節。 C代碼是否用'printf(「%zu%zu \ n」,sizeof(double *),sizeof(unsigned))來報告;'? – chux 2014-12-03 23:03:23

回答

-2
here is the algorithm, is a mix between C and pseudo code 
My suggestion is to write this program in C. 
Then have the compiler output the related asm language 
then use that asm output as a guide in writing your own program 

! ---------------------------------------------------------- 
! This program reads a series of input data values and 
! computes their arithmetic, geometric and harmonic means. 
! Since geometric mean requires taking n-th root, all input 
! data item must be all positive (a special requirement of 
! this program , although it is not absolutely necessary). 
! If an input item is not positive, it should be ignored. 
! Since some data items may be ignored, this program also 
! checks to see if no data items remain! 
! ---------------------------------------------------------- 

PROGRAM ComputingMeans 
    IMPLICIT NONE 

    REAL :: X 
    REAL :: Sum, Product, InverseSum 
    REAL :: Arithmetic, Geometric, Harmonic 
    INTEGER :: Count, TotalNumber, TotalValid 

    Sum  = 0.0      ! for the sum 
    Product = 1.0      ! for the product 
    InverseSum = 0.0      ! for the sum of 1/x 
    TotalValid = 0      ! # of valid items 

    READ(*,*) TotalNumber    ! read in # of items 
    DO Count = 1, TotalNumber   ! for each item ... 
     READ(*,*) X      ! read it in 
     WRITE(*,*) 'Input item ', Count, ' --> ', X 
     IF (X <= 0.0) THEN    ! if it is non-positive 
     WRITE(*,*) 'Input <= 0. Ignored' ! ignore it 
     ELSE        ! otherwise, 
     TotalValid = TotalValid + 1 ! count it in 
     Sum  = Sum + X   ! compute the sum, 
     Product = Product * X  ! the product 
     InverseSum = InverseSum + 1.0/X  ! and the sum of 1/x 
     END IF 
    END DO 

    IF (TotalValid > 0) THEN    ! are there valid items? 
     Arithmetic = Sum/TotalValid  ! yes, compute means 
     Geometric = Product**(1.0/TotalValid) 
     Harmonic = TotalValid/InverseSum 

     WRITE(*,*) 'No. of valid items --> ', TotalValid 
     WRITE(*,*) 'Arithmetic mean --> ', Arithmetic 
     WRITE(*,*) 'Geometric mean  --> ', Geometric 
     WRITE(*,*) 'Harmonic mean  --> ', Harmonic 
    ELSE         ! no, display a message 
     WRITE(*,*) 'ERROR: none of the input is positive' 
    END IF 

END PROGRAM ComputingMeans 
+0

這不是彙編代碼,這是原始問題的要求 – 2014-12-04 15:57:27

0

是似乎有float VS double混亂。你傳入一個double數組,但幾乎所有的asm代碼都需要浮點數:你使用ss指令,你假設大小爲4,你也返回一個浮點數。 –  傑斯特

有浮動和雙打的問題!我真的很感激你的迴應。我很困惑,因爲教練告訴我們在我們的程序集程序中使用了浮點數,他在示例驅動程序中使用了雙打。我跟老師說話,他已經修好了他的指示。我再次感謝你! - Tyler Weaver