ref与out的区别(反汇编篇)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace refout
{
    class Program
    {
        static void Main(string[] args)
        {
            testParams tp = new testParams();
            Int32 x = 23;
            Int32 y = 45;
            Console.WriteLine("x={0},y={1}",x,y);
            tp.changeWithoutRef(x,y);
            Console.WriteLine("没加ref的change之后:");
            Console.WriteLine("x={0},y={1}", x, y);
            tp.changeWithRef(ref x,ref y);
            Console.WriteLine("加ref的change之后:");
            Console.WriteLine("x={0},y={1}", x, y);
            Console.ReadKey();
        }
    }

    public class testParams{
      public void changeWithoutRef(Int32 a,Int32 b){//此处取断点
          Int32 temp;
          temp = a;
          a = b;
          b = temp;
      }

      public void changeWithRef(ref Int32 a,ref Int32 b) {//此处取断点
          Int32 temp=0;
          temp = a;
          a = b;
          b = temp;
      }
    }
}

 

运行后,程序断下,按调试-->窗口-->反汇编进入相应方法的反汇编窗口,我们会看到:

对于方法 changeWithoutRef

--- d:\用户目录\documents\visual studio 2010\Projects\refout\refout\Program.cs -----
      public void changeWithoutRef(Int32 a,Int32 b){
00000000  push        ebp
00000001  mov         ebp,esp
00000003  push        edi
00000004  push        esi
00000005  push        ebx
00000006  sub         esp,38h
00000009  mov         esi,ecx
0000000b  lea         edi,[ebp-38h]
0000000e  mov         ecx,0Bh
00000013  xor         eax,eax
00000015  rep stos    dword ptr es:[edi]
00000017  mov         ecx,esi
00000019  xor         eax,eax
0000001b  mov         dword ptr [ebp-1Ch],eax
0000001e  mov         dword ptr [ebp-3Ch],ecx
00000021  mov         dword ptr [ebp-40h],edx
00000024  cmp         dword ptr ds:[00249284h],0
0000002b  je          00000032
0000002d  call        6EA2EBA9
00000032  xor         edx,edx
00000034  mov         dword ptr [ebp-44h],edx
00000037  nop
          Int32 temp;
          temp = a;
00000038  mov         eax,dword ptr [ebp-40h]
0000003b  mov         dword ptr [ebp-44h],eax    //直接将eax的值进行传递
          a = b;
0000003e  mov         eax,dword ptr [ebp+8]
00000041  mov         dword ptr [ebp-40h],eax
          b = temp;
00000044  mov         eax,dword ptr [ebp-44h]
00000047  mov         dword ptr [ebp+8],eax
      }
0000004a  nop
0000004b  lea         esp,[ebp-0Ch]
0000004e  pop         ebx
0000004f  pop         esi
00000050  pop         edi
00000051  pop         ebp
00000052  ret         4

 

而对于方法changeWithRef

--- d:\用户目录\documents\visual studio 2010\Projects\refout\refout\Program.cs -----
      public void changeWithRef(ref Int32 a,ref Int32 b) {
00000000  push        ebp
00000001  mov         ebp,esp
00000003  push        edi
00000004  push        esi
00000005  push        ebx
00000006  sub         esp,38h
00000009  mov         esi,ecx
0000000b  lea         edi,[ebp-38h]
0000000e  mov         ecx,0Bh
00000013  xor         eax,eax
00000015  rep stos    dword ptr es:[edi]
00000017  mov         ecx,esi
00000019  xor         eax,eax
0000001b  mov         dword ptr [ebp-1Ch],eax
0000001e  mov         dword ptr [ebp-3Ch],ecx
00000021  mov         dword ptr [ebp-40h],edx
00000024  cmp         dword ptr ds:[00239284h],0
0000002b  je          00000032
0000002d  call        6E92EB41
00000032  xor         edx,edx
00000034  mov         dword ptr [ebp-44h],edx
00000037  nop
          Int32 temp=0;
00000038  xor         edx,edx
0000003a  mov         dword ptr [ebp-44h],edx
          temp = a;
0000003d  mov         eax,dword ptr [ebp-40h]
00000040  mov         eax,dword ptr [eax]     //取得eax的地址
00000042  mov         dword ptr [ebp-44h],eax   //再将eax的值进行传递,注意此时的eax已经成为原值的地址
          a = b;
00000045  mov         eax,dword ptr [ebp+8]
00000048  mov         eax,dword ptr [eax]
0000004a  mov         edx,dword ptr [ebp-40h]
0000004d  mov         dword ptr [edx],eax
          b = temp;
0000004f  mov         eax,dword ptr [ebp+8]
00000052  mov         edx,dword ptr [ebp-44h]
00000055  mov         dword ptr [eax],edx
      }
00000057  nop
00000058  lea         esp,[ebp-0Ch]
0000005b  pop         ebx
0000005c  pop         esi
0000005d  pop         edi
0000005e  pop         ebp
0000005f  ret         4

 

结论:无论值类型还是引用类型,不加ref就是传值,加了ref就是传地址

posted @ 2012-11-23 07:58  FiberHomer  阅读(365)  评论(0编辑  收藏  举报