I have been working on an .NET issue where release mode code run in the debugger, and release mode code run outside produce different results. I think the problem lies in the optimizations (debug mode on a release project seems to disable JIT optimizations)
in release mode with debugger it prints 97.08 without it prints 97.09 .. the C# code in question is included in the debug version .. the IL generated is obviously the same in both circumstances.
in release mode with the debugger the following native code is produced
static void Main(string[] args)
{
float low = 7f;
00000000 sub esp,18h
00000003 mov dword ptr [esp],ecx
00000006 cmp dword ptr ds:[00918888h],0
0000000d je 00000014
0000000f call 794411F6
00000014 fldz
00000016 fstp dword ptr [esp+4]
0000001a fldz
0000001c fstp dword ptr [esp+8]
00000020 mov dword ptr [esp+4],40E00000h
float high = 100f;
00000028 mov dword ptr [esp+8],42C80000h
low = ((high + low) / 2f);
00000030 fld dword ptr [esp+8]
00000034 fadd dword ptr [esp+4]
00000038 fdiv dword ptr ds:[00C51270h]
0000003e fstp dword ptr [esp+4]
low = ((high + low) / 2f);
00000042 fld dword ptr [esp+8]
00000046 fadd dword ptr [esp+4]
0000004a fdiv dword ptr ds:[00C51278h]
00000050 fstp dword ptr [esp+4]
low = ((int)(low * 100f)) / 100f;
00000054 fld dword ptr [esp+4]
00000058 fmul dword ptr ds:[00C51280h]
0000005e fstp qword ptr [esp+10h]
00000062 movsd xmm0,mmword ptr [esp+10h]
00000068 cvttsd2si eax,xmm0
0000006c mov dword ptr [esp+0Ch],eax
00000070 fild dword ptr [esp+0Ch]
00000074 fstp dword ptr [esp+0Ch]
00000078 fld dword ptr [esp+0Ch]
0000007c fdiv dword ptr ds:[00C51288h]
00000082 fstp dword ptr [esp+4]
low = ((high + low) / 2f);
00000086 fld dword ptr [esp+8]
0000008a fadd dword ptr [esp+4]
0000008e fdiv dword ptr ds:[00C51290h]
00000094 fstp dword ptr [esp+4]
low = ((int)(low * 100f)) / 100f;
00000098 fld dword ptr [esp+4]
0000009c fmul dword ptr ds:[00C51298h]
000000a2 fstp qword ptr [esp+10h]
000000a6 movsd xmm0,mmword ptr [esp+10h]
000000ac cvttsd2si eax,xmm0
000000b0 mov dword ptr [esp+0Ch],eax
000000b4 fild dword ptr [esp+0Ch]
000000b8 fstp dword ptr [esp+0Ch]
000000bc fld dword ptr [esp+0Ch]
000000c0 fdiv dword ptr ds:[00C512A0h]
000000c6 fstp dword ptr [esp+4]
low = ((high + low) / 2f);
000000ca fld dword ptr [esp+8]
000000ce fadd dword ptr [esp+4]
000000d2 fdiv dword ptr ds:[00C512A8h]
000000d8 fstp dword ptr [esp+4]
low = ((int)(low * 100f)) / 100f;
000000dc fld dword ptr [esp+4]
000000e0 fmul dword ptr ds:[00C512B0h]
000000e6 fstp qword ptr [esp+10h]
000000ea movsd xmm0,mmword ptr [esp+10h]
000000f0 cvttsd2si eax,xmm0
000000f4 mov dword ptr [esp+0Ch],eax
000000f8 fild dword ptr [esp+0Ch]
000000fc fstp dword ptr [esp+0Ch]
00000100 fld dword ptr [esp+0Ch]
00000104 fdiv dword ptr ds:[00C512B8h]
0000010a fstp dword ptr [esp+4]
low = ((high + low) / 2f);
0000010e fld dword ptr [esp+8]
00000112 fadd dword ptr [esp+4]
00000116 fdiv dword ptr ds:[00C512C0h]
0000011c fstp dword ptr [esp+4]
low = ((int)(low * 100f)) / 100f;
00000120 fld dword ptr [esp+4]
00000124 fmul dword ptr ds:[00C512C8h]
0000012a fstp qword ptr [esp+10h]
0000012e movsd xmm0,mmword ptr [esp+10h]
00000134 cvttsd2si eax,xmm0
00000138 mov dword ptr [esp+0Ch],eax
0000013c fild dword ptr [esp+0Ch]
00000140 fstp dword ptr [esp+0Ch]
00000144 fld dword ptr [esp+0Ch]
00000148 fdiv dword ptr ds:[00C512D0h]
0000014e fstp dword ptr [esp+4]
Console.WriteLine(low);
00000152 push dword ptr [esp+4]
00000156 call 78767E54
0000015b nop
Console.ReadLine ();
0000015c call 78767C6C
00000161 nop
}
00000162 nop
00000163 add esp,18h
00000166 ret
In release mode without the debugger, the following native assembly is produced
00000000 sub esp,0Ch
00000003 fld dword ptr ds:[00C40198h]
00000009 fld dword ptr ds:[00C401A0h]
0000000f fadd st(1),st
00000011 fxch st(1)
00000013 fdiv dword ptr ds:[00C401A8h]
00000019 fadd st,st(1)
0000001b fdiv dword ptr ds:[00C401B0h]
00000021 fmul dword ptr ds:[00C401B8h]
00000027 fstp qword ptr [esp+4]
0000002b movsd xmm0,mmword ptr [esp+4]
00000031 cvttsd2si eax,xmm0
00000035 mov dword ptr [esp],eax
00000038 fild dword ptr [esp]
0000003b fstp dword ptr [esp]
0000003e fld dword ptr [esp]
00000041 fdiv dword ptr ds:[00C401C0h]
00000047 fadd st,st(1)
00000049 fdiv dword ptr ds:[00C401C8h]
0000004f fmul dword ptr ds:[00C401D0h]
00000055 fstp qword ptr [esp+4]
00000059 movsd xmm0,mmword ptr [esp+4]
0000005f cvttsd2si eax,xmm0
00000063 mov dword ptr [esp],eax
00000066 fild dword ptr [esp]
00000069 fstp dword ptr [esp]
0000006c fld dword ptr [esp]
0000006f fdiv dword ptr ds:[00C401D8h]
00000075 fadd st,st(1)
00000077 fdiv dword ptr ds:[00C401E0h]
0000007d fmul dword ptr ds:[00C401E8h]
00000083 fstp qword ptr [esp+4]
00000087 movsd xmm0,mmword ptr [esp+4]
0000008d cvttsd2si eax,xmm0
00000091 mov dword ptr [esp],eax
00000094 fild dword ptr [esp]
00000097 fstp dword ptr [esp]
0000009a fld dword ptr [esp]
0000009d fdiv dword ptr ds:[00C401F0h]
000000a3 faddp st(1),st
000000a5 fdiv dword ptr ds:[00C401F8h]
000000ab fmul dword ptr ds:[00C40200h]
000000b1 fstp qword ptr [esp+4]
000000b5 movsd xmm0,mmword ptr [esp+4]
000000bb cvttsd2si eax,xmm0
000000bf mov dword ptr [esp],eax
000000c2 fild dword ptr [esp]
000000c5 fstp dword ptr [esp]
000000c8 fld dword ptr [esp]
000000cb fdiv dword ptr ds:[00C40208h]
000000d1 cmp dword ptr ds:[02271084h],0
000000d8 jne 000000EC
000000da mov ecx,1
000000df fstp dword ptr [esp]
000000e2 call 7870D79C
000000e7 fld dword ptr [esp]
000000ea jmp 000000EC
000000ec mov eax,dword ptr ds:[02271084h]
000000f1 sub esp,4
000000f4 fstp dword ptr [esp]
000000f7 mov ecx,eax
000000f9 mov eax,dword ptr [ecx]
000000fb call dword ptr [eax+000000CCh]
00000101 call 78776B48
00000106 mov ecx,eax
00000108 mov eax,dword ptr [ecx]
0000010a call dword ptr [eax+64h]
0000010d add esp,0Ch
00000110 ret
It has been quite a while since I have worked with assembly (too long imo) but from looking through this the differences are significant.
I also have a secondary question as something struck me as quite odd ...
What is the point of this?
000000ea jmp 000000EC
000000ec mov eax,dword ptr ds:[02271084h]