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