main.cpp
#include <stdio.h>
#include <float.h>
extern "C" bool CalcMinMax(const float* a, int n, float* min, float* max);
bool CalcMinMaxCpp(const float* a, int n, float* min, float* max)
{
if (n <= 0)
return false;
float min_a = FLT_MAX;
float max_a = -FLT_MAX;
for (int i = 0; i < n; i++)
{
if (a[i] < min_a)
min_a = a[i];
if (a[i] > max_a)
max_a = a[i];
}
*min = min_a;
*max = max_a;
return true;
}
int main(int argc, char* argv[])
{
float a[] = { 20, -12, 42, 97, 14, -26, 57, 74, -18, 63, 34, -9};
const int n = sizeof(a) / sizeof(float);
float min1, max1;
float min2, max2;
CalcMinMaxCpp(a, n, &min1, &max1);
CalcMinMax(a, n, &min2, &max2);
for (int i = 0; i < n; i++)
printf("a[%2d] = %8.2f\n", i, a[i]);
printf("\n");
printf("min1: %8.2f max1: %8.2f\n", min1, max1);
printf("min2: %8.2f max2: %8.2f\n", min2, max2);
}
calcminmax.asm
; Name: calcminmax.asm
;
; Build: g++ -c -m32 main.cpp -o main.o
; nasm -f elf32 -o calcminmax.o calcminmax.asm
; g++ -m32 -o calcminmax calcminmax.o main.o
;
; Source: Modern x86 Assembly Language Programming p.116
global CalcMinMax
section .data
r4_MinFloat dq 0xff7fffff ;smallest float number
r4_MaxFloat dq 0x7f7fffff ;largest float number
section .text
; extern "C" bool CalcMinMax(const float* a, int n, float* min, float* max);
;
; Description: The following function calculates the min and max values
; of a single-precision floating-point array.
;
; Returns: 0 = invalid 'n'
; 1 = valid 'n'
%define a [ebp+8]
%define n [ebp+12]
%define min [ebp+16]
%define max [ebp+20]
CalcMinMax:
push ebp
mov ebp,esp
; Load argument values and make sure 'n' is valid.
xor eax,eax ;set error return code
mov edx,a ;edx = 'a'
mov ecx,n ;ecx = 'n'
test ecx,ecx
jle .done ;jump if 'n' <= 0
fld qword[r4_MinFloat] ;initial max_a value
fld qword[r4_MaxFloat] ;initial min_a value
; Find min and max of input array
.l1:
fld dword[edx] ;load *a
fld st0 ;duplicate *a on stack
fcomi st0,st2 ;compare *a with min
fcmovnb st0,st2 ;ST(0) equals smaller val
fstp st2 ;save new min value
fcomi st0,st2 ;compare *a with max_a
fcmovb st0,st2 ;st(0) equals larger val
fstp st2 ;save new max value
add edx,4 ;point to next a[i]
dec ecx
jnz .l1 ;repeat loop until finished
; Save results
mov eax,min
fstp dword[eax] ;save final min
mov eax,max
fstp dword[eax] ;save final max
mov eax,1 ;set success return code
.done:
pop ebp
ret
build
g++ -c -m32 main.cpp -o main.o
nasm -f elf32 -o calcminmax.o calcminmax.asm
g++ -m32 -o calcminmax calcminmax.o main.o