Reverse Engineering for Beginners

(avery) #1

CHAPTER 27. WORKING WITH FLOATING POINT NUMBERS USING SIMD CHAPTER 27. WORKING WITH FLOATING POINT NUMBERS USING SIMD


27.3 Comparison example


#include <stdio.h>


double d_max (double a, double b)
{
if (a>b)
return a;


return b;
};


int main()
{
printf ("%f\n", d_max (1.2, 3.4));
printf ("%f\n", d_max (5.6, -4));
};


27.3.1 x64


Listing 27.7: Optimizing MSVC 2012 x64

a$ = 8
b$ = 16
d_max PROC
comisd xmm0, xmm1
ja SHORT $LN2@d_max
movaps xmm0, xmm1
$LN2@d_max:
fatret 0
d_max ENDP


Optimizing MSVC generates a code very easy to understand.


COMISDis “Compare Scalar Ordered Double-Precision Floating-Point Values and Set EFLAGS”. Essentially, that is what it does.


Non-optimizing MSVC generates more redundant code, but it is still not hard to understand:


Listing 27.8: MSVC 2012 x64

a$ = 8
b$ = 16
d_max PROC
movsdx QWORD PTR [rsp+16], xmm1
movsdx QWORD PTR [rsp+8], xmm0
movsdx xmm0, QWORD PTR a$[rsp]
comisd xmm0, QWORD PTR b$[rsp]
jbe SHORT $LN1@d_max
movsdx xmm0, QWORD PTR a$[rsp]
jmp SHORT $LN2@d_max
$LN1@d_max:
movsdx xmm0, QWORD PTR b$[rsp]
$LN2@d_max:
fatret 0
d_max ENDP


However, GCC 4.4.6 did more optimizations and used theMAXSD(“Return Maximum Scalar Double-Precision Floating-Point
Value”) instruction, which just choose the maximum value!


Listing 27.9: Optimizing GCC 4.4.6 x64

d_max:
maxsd xmm0, xmm1
ret

Free download pdf