main.cpp
#include "stdio.h"
extern "C" double CalcSum(float a, double b, float c, double d, float e, double f);
extern "C" double CalcDist(int x1, double x2, long long y1, double y2, float z1, short z2);
void CalcSumCpp(void)
{
float a = 10.0f;
double b = 20.0;
float c = 0.5f;
double d = 0.0625;
float e = 15.0f;
double f = 0.125;
double sum = CalcSum(a, b, c, d, e, f);
printf("\nResults for CalcSum()\n");
printf("a: %10.4f b: %10.4lf c: %10.4f\n", a, b, c);
printf("d: %10.4lf e: %10.4f f: %10.4lf\n", d, e, f);
printf("\nsum: %10.4lf\n", sum);
}
void CalcDistCpp(void)
{
int x1 = 5;
double x2 = 12.875;
long long y1 = 17;
double y2 = 23.1875;
float z1 = -2.0625;
short z2 = -6;
double dist = CalcDist(x1, x2, y1, y2, z1, z2);
printf("\nResults for CalcDist()\n");
printf("x1: %10d x2: %10.4lf\n", x1, x2);
printf("y1: %10lld y2: %10.4lf\n", y1, y2);
printf("z1: %10.4f z2: %10d\n", z1, z2);
printf("\ndist: %12.6lf\n", dist);
}
int main(int argc, char* argv[])
{
CalcSumCpp();
CalcDistCpp();
return 0;
}
floatingpointarithmetic.asm
; Name: floatingpointarithmetic.asm
;
; Build: g++ -c main.cpp -o main.o
; nasm -f elf64 -o floatingpointarithmetic.o floatingpointarithmetic.asm
; g++ -o floatingpointarithmetic floatingpointarithmetic.o main.o
;
; Source: Modern x86 Assembly Language Programming p.519
global CalcSum
global CalcDist
section .text
; extern "C" double CalcSum(float a, double b, float c, double d, float e, double f);
;
; Description: The following function demonstrates how to access
; floating-point argument values in an x86-64 function.
CalcSum:
; registers: xmm0 = a
; xmm1 = b
; xmm2 = c
; xmm3 = d
; xmm4 = e
; xmm5 = f
; Sum the argument values
cvtss2sd xmm0,xmm0 ;promote a to DPFP
addsd xmm0,xmm1 ;xmm0 = a + b
cvtss2sd xmm2,xmm2 ;promote c to DPFP
addsd xmm0,xmm2 ;xmm0 = a + b + c
addsd xmm0,xmm3 ;xmm0 = a + b + c + d
cvtss2sd xmm4,xmm4 ;promote e to DPFP
addsd xmm0,xmm4 ;xmm0 = a + b + c + d + e
addsd xmm0,xmm5 ;xmm0 = a + b + c + d + e + f
ret
; extern "C" double CalcDist(int x1, double x2, long long y1, double y2, float z1, short z2);
;
; Description: The following function demonstrates how to access mixed
; floating-point and integer arguments values in an
; x86-64 function.
CalcDist:
; registers: edi = x1
; xmm0 = x2
; rsi = y1
; xmm1 = y2
; xmm2 = z1
; dl = z2 (in reality z2 is stored in edx)
; Calculate xd = (x2 - x1) * (x2 - x1)
cvtsi2sd xmm3,edi ;convert x1 to DPFP
subsd xmm0,xmm3 ;xmm0 = x2 - x1
mulsd xmm0,xmm0 ;xmm0 = xd
; Calculate yd = (y2 - y1) * (y2 - y1)
cvtsi2sd xmm4,rsi ;convert y1 to DPFP
subsd xmm1,xmm4 ;xmm1 = y2 - y1
mulsd xmm1,xmm1 ;xmm1 = yd
; Calculate zd = (z2 - z1) * (z2 - z1)
;movss xmm0,real4 ptr [rsp+40] ;xmm=0 = z1
cvtss2sd xmm3,xmm2 ;convert z1 to DPFP
movsx eax,dl ;eax = sign-extend z2
cvtsi2sd xmm2,eax ;convert z2 to DPFP
subsd xmm2,xmm3 ;xmm2 = z2 - z1
mulsd xmm2,xmm2 ;xmm2 = zd
; Calculate final distance sqrt(xd + yd + zd)
addsd xmm0,xmm1 ;xmm0 = xd + yd
addsd xmm0,xmm2 ;xmm0 = xd + yd + zd
sqrtsd xmm0,xmm0 ;xmm0 = sqrt(xd + yd + zd)
ret
build
g++ -c main.cpp -o main.o
nasm -f elf64 -o floatingpointarithmetic.o floatingpointarithmetic.asm
g++ -o floatingpointarithmetic floatingpointarithmetic.o main.o