3.3. TEMPERATURE CONVERTING
- The address ofprintf()is first loaded in theESIregister, so the subsequentprintf()calls are
done just by theCALL ESIinstruction. It’s a very popular compiler technique, possible if several
consequent calls to the same function are present in the code, and/or if there is a free register which
can be used for this. - We see theADD EAX, -32instruction at the place where 32 has to be subtracted from the value.
EAX=EAX+ (−32)is equivalent toEAX=EAX− 32 and somehow, the compiler decided to useADD
instead ofSUB. Maybe it’s worth it, it’s hard to be sure. - TheLEAinstructionisusedwhenthevalueistobemultipliedby5:lea ecx, DWORD PTR [eax+eax*4].
Yes,i+i∗ 4 is equivalent toi∗ 5 andLEAworks faster thenIMUL.
By the way, theSHL EAX, 2 / ADD EAX, EAXinstruction pair could be also used here instead—
some compilers do it like. - The division by multiplication trick (3.9 on page 497) is also used here.
- main()returns 0 if we don’t havereturn 0at its end. The C99 standard tells us [ISO/IEC 9899:TC3
(C C99 standard), (2007)5.1.2.2.3] thatmain()will return 0 in case thereturnstatement is missing.
This rule works only for themain()function.
Though, MSVC doesn’t officially support C99, but maybe it support it partially?
Optimizing MSVC 2012 x64
The code is almost the same, but we can findINT 3instructions after eachexit()call.
xor ecx, ecx
call QWORD PTR __imp_exit
int 3
INT 3is a debugger breakpoint.
It is known thatexit()is one of the functions which can never return^2 , so if it does, something really
odd has happened and it’s time to load the debugger.
3.3.2 Floating-point values
#include <stdio.h>
#include <stdlib.h>
int main()
{
double celsius, fahr;
printf ("Enter temperature in Fahrenheit:\n");
if (scanf ("%lf", &fahr)!=1)
{
printf ("Error while parsing your input\n");
exit(0);
};
celsius = 5 * (fahr-32) / 9;
if (celsius<-273)
{
printf ("Error: incorrect temperature!\n");
exit(0);
};
printf ("Celsius: %lf\n", celsius);
};
MSVC 2010 x86 usesFPUinstructions...
Listing 3.2: Optimizing MSVC 2010 x86
$SG4038 DB 'Enter temperature in Fahrenheit:', 0aH, 00H
$SG4040 DB '%lf', 00H
(^2) another popular one islongjmp()