ref与out的区别(反汇编篇)
2012-11-23 07:58
246 查看
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就是传地址
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就是传地址
相关文章推荐
- 【转】C#中out和ref的区别
- 关于ref和out的详细区别
- C#中out和ref之间的区别
- c# 中ref ,out ,params 三种修饰符的作用与区别
- out,ref,params的区别
- Ref 和Out 区别
- ref和out的区别,以及params的作用
- C#中out和ref之间的区别
- ref与out的区别
- C#中 ref和out关键字的区别
- C# 中ref out区别
- ref和out区别概要
- C#中out和ref之间的区别
- ref和out的使用与区别【转】
- c#中out和ref的使用区别 [转]
- c#方法中调用参数的值传递方式和引用传递方式,以及ref与out的区别
- out 和 ref 的区别
- C#中的Params、ref、out的区别
- C#/.NET中关于ref与out的区别
- c#中out与ref的用法与区别