2014-12-03 43 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