Star InactiveStar InactiveStar InactiveStar InactiveStar Inactive
 
main.cpp
#include <stdio.h>
#include <math.h>

extern "C" bool CalcMeanStdev(const double* a, int n, double* mean, double* stdev);

bool CalcMeanStdevCpp(const double* a, int n, double* mean, double* stdev)
{
    if (n <= 1)
        return false;

    double sum = 0.0;
    for (int i = 0; i < n; i++)
        sum += a[i];
    *mean = sum / n;

    sum = 0.0;
    for (int i = 0; i < n; i++)
    {
            double temp = a[i] - *mean;
            sum += temp * temp;
    }

    *stdev = sqrt(sum / (n - 1));
    return true;
}

int main(int argc, char* argv[])
{
    double a[] = { 10, 2, 33, 15, 41, 24, 75, 37, 18, 97};
    const int n = sizeof(a) / sizeof(double);
    double mean1, stdev1;
    double mean2, stdev2;

    CalcMeanStdevCpp(a, n, &mean1, &stdev1);
    CalcMeanStdev(a, n, &mean2, &stdev2);

    for (int i = 0; i < n; i++)
        printf("a[%d] = %g\n", i, a[i]);

    printf("\n");
    printf("mean1: %g stdev1: %g\n", mean1, stdev1);
    printf("mean2: %g stdev2: %g\n", mean2, stdev2);
}
calcmeanstdev.asm
; Name:     calcmeanstdev.asm
;
; Build:    g++ -c -m32 main.cpp -o main.o
;           nasm -f elf32 -o calcmeanstdev.o calcmeanstdev.asm
;           g++ -m32 -o calcmeanstdev calcmeanstdev.o main.o
;
; Source:   Modern x86 Assembly Language Programming p.112

global  CalcMeanStdev

section .text

; extern "C" bool CalcMeanStdev(const double* a, int n, double* mean, double* stdev);
;
; Description:  The following function calculates the mean and
;               standard deviation of the values in an array.
;
; Returns:      0 = invalid 'n'
;               1 = valid 'n' 

%define a       [ebp+8]
%define n       [ebp+12]
%define mean    [ebp+16]
%define stdev   [ebp+20]
%define i       [ebp-4]

CalcMeanStdev:
    push    ebp
    mov     ebp,esp
    sub     esp,4
    ; Make sure 'n' is valid
    xor     eax,eax
    mov     ecx,n
    cmp     ecx,1
    jle     .done                   ;jump if n <= 1
    dec     ecx
    mov     i,ecx                   ;save n - 1 for later
    inc     ecx
    ; Compute sample mean
    mov     edx,a                   ;edx = 'a'
    fldz                            ;sum = 0.0
.l1:
    fadd    qword[edx]              ;sum += *a
    add     edx,8                   ;a++
    dec     ecx
    jnz     .l1
    fidiv   dword n                 ;mean = sum / n
    ; Compute sample stdev
    mov     edx,a                   ;edx = 'a'
    mov     ecx,n                   ;n
    fldz                            ;sum = 0.0, ST(1) = mean
.l2:
    fld     qword [edx]             ;ST(0) = *a,
    fsub    st0,st2                 ;ST(0) = *a - mean
    fmul    st0,st0                 ;ST(0) = (*a - mean) ^ 2
    faddp                           ;update sum
    add     edx,8
    dec     ecx
    jnz     .l2
    fidiv   dword i                 ;var = sum / (n - 1)
    fsqrt                           ;final stdev
    ; Save results
    mov     eax,stdev
    fstp    qword [eax]             ;save stdev
    mov     eax,mean
    fstp    qword [eax]             ;save mean
    mov     eax,1                   ;set success return code
.done:
    mov     esp,ebp
    pop     ebp
    ret
build
g++ -c -m32 main.cpp -o main.o
nasm -f elf32 -o calcmeanstdev.o calcmeanstdev.asm
g++ -m32 -o calcmeanstdev calcmeanstdev.o main.o