调用方法

时间:2016-04-22 10:39:41

标签: c# jit

我正在阅读这本书Pro .net Performance。它声明:

  

以下是托管方法的典型序言和结尾   编译为32位机器代码(这不是实际的生产代码   由JIT编译器生成,它采用了许多优化   在第10章中讨论过)。该方法有四个局部变量,其中   存储在序言中立即分配并立即回收   结语:

书籍声称这种方法:

int Calculation(int a, int b)
{
  int x = a + b;
  int y = a - b;
  int z = b - a;
  int w = 2 * b + 2 * a;
  return x + y + z + w;
}

将被翻译为:

; parameters are passed on the stack in [esp+4] and [esp+8]
push ebp
mov ebp, esp
add esp, 16 ; allocates storage for four local variables
mov eax, dword ptr [ebp+8]
add eax, dword ptr [ebp+12]
mov dword ptr [ebp-4], eax
; ...similar manipulations for y, z, w
mov eax, dword ptr [ebp-4]
add eax, dword ptr [ebp-8]
add eax, dword ptr [ebp-12]
add eax, dword ptr [ebp-16] ; eax contains the return value
mov esp, ebp ; restores the stack frame, thus reclaiming the local storage space
pop ebp
ret 8 ; reclaims the storage for the two parameters

为了测试它,我创建了以下类:

class TestCall
    {
        public static void Main(string[] args)
        {
            TestCall testCall=new TestCall();
            int sum=0;
            for (int i = 0; i < 5; i++)
            {
                sum += testCall.Calculation(5, 6);
            }
            Console.WriteLine(sum);
        }
        int Calculation(int a, int b)
        {
            int x = a + b;
            int y = a - b;
            int z = b - a;
            int w = 2 * b + 2 * a;
            return x + y + z + w;
        }
    }

调试时,Visual Studio的反汇编窗口显示Calculation方法:

    23:         {
005B2EB8  push        ebp  
005B2EB9  mov         ebp,esp  
005B2EBB  push        edi  
005B2EBC  push        esi  
005B2EBD  push        ebx  
005B2EBE  sub         esp,48h  
005B2EC1  mov         esi,ecx  
005B2EC3  lea         edi,[ebp-38h]  
005B2EC6  mov         ecx,0Bh  
005B2ECB  xor         eax,eax  
005B2ECD  rep stos    dword ptr es:[edi]  
005B2ECF  mov         ecx,esi  
005B2ED1  mov         dword ptr [ebp-3Ch],ecx  
005B2ED4  mov         dword ptr [ebp-40h],edx  
005B2ED7  cmp         dword ptr ds:[12C668h],0  
005B2EDE  je          005B2EE5  
005B2EE0  call        6970CB2D  
005B2EE5  xor         edx,edx  
005B2EE7  mov         dword ptr [ebp-54h],edx  
005B2EEA  xor         edx,edx  
005B2EEC  mov         dword ptr [ebp-4Ch],edx  
005B2EEF  xor         edx,edx  
005B2EF1  mov         dword ptr [ebp-50h],edx  
005B2EF4  xor         edx,edx  
005B2EF6  mov         dword ptr [ebp-48h],edx  
005B2EF9  xor         edx,edx  
005B2EFB  mov         dword ptr [ebp-44h],edx  
005B2EFE  nop  
    24:             int x = a + b;
005B2EFF  mov         eax,dword ptr [ebp-40h]  
005B2F02  add         eax,dword ptr [ebp+8]  
005B2F05  mov         dword ptr [ebp-44h],eax  
    25:             int y = a - b;
005B2F08  mov         eax,dword ptr [ebp-40h]  
005B2F0B  sub         eax,dword ptr [ebp+8]  
005B2F0E  mov         dword ptr [ebp-48h],eax  
    26:             int z = b - a;
005B2F11  mov         eax,dword ptr [ebp+8]  
005B2F14  sub         eax,dword ptr [ebp-40h]  
005B2F17  mov         dword ptr [ebp-4Ch],eax  
    27:             int w = 2*b + 2*a;
005B2F1A  mov         eax,dword ptr [ebp+8]  
005B2F1D  add         eax,eax  
005B2F1F  mov         edx,dword ptr [ebp-40h]  
    27:             int w = 2*b + 2*a;
005B2F22  add         edx,edx  
005B2F24  add         eax,edx  
005B2F26  mov         dword ptr [ebp-50h],eax  
    28:             return x + y + z + w;
005B2F29  mov         eax,dword ptr [ebp-44h]  
005B2F2C  add         eax,dword ptr [ebp-48h]  
005B2F2F  add         eax,dword ptr [ebp-4Ch]  
005B2F32  add         eax,dword ptr [ebp-50h]  
005B2F35  mov         dword ptr [ebp-54h],eax  
005B2F38  nop  
005B2F39  jmp         005B2F3B  
    29:         }
005B2F3B  mov         eax,dword ptr [ebp-54h]  
005B2F3E  lea         esp,[ebp-0Ch]  
005B2F41  pop         ebx  
005B2F42  pop         esi  
005B2F43  pop         edi  
005B2F44  pop         ebp  
005B2F45  ret         4  

为什么会有如此大的序幕?我的窗户是32位的。项目目标是.net 4.5。调试开启,优化关闭。

0 个答案:

没有答案