谐波平均值产生不正确的结果

时间:2014-12-03 22:30:30

标签: c linux assembly 64-bit average

作为家庭作业,我们需要使用由C程序驱动的装配程序来计算调和平均值。

我们使用的是64位Linux机器,需要使用64位浮点数。

我是大会的新手。我为任何糟糕的编码做法道歉,或者我的代码是错误的。


代码的问题是结果只返回以浮点格式输入的最后一个数字。我不知道错误发生在哪里,虽然我认为它位于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 个答案:

答案 0 :(得分:-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