乱糟糟的狼窝
歪酷博客
日 历
网志文件夹
· 所有网志
· 日记
· 学习
· 技术
· 未分类
搜 索
友 情 链 接
· 歪酷博客
· 管理我的Blog
· 猫猫头之屋
· Chsoft(阿紫的小屋吧)
· Celinna的梦想

订阅 RSS

0017442

歪酷博客

居然有这么一个狼窝。。。反正只有一头狼,就无所谓把东西分门别类的放好了,都是乱糟糟的,越乱越好
« 上一篇: 原来我们的Delegate都是WaitCallBck 下一篇: 异步调用拾漏补遗 »
Jewelry_wolf @ 2004-09-03 17:31

一切都在bbs因SilenceHeard的一个问题而起。。。
SilenceHeard:
需要引用一个bool值,却找不到方法。求助

int i = 5;
object o = i;

引用的目的是通过o来修改 i 的值

boxing只能负责类型转换。

int i = 5;
object o = i;

对o进行修改以后, i的值还是5。这不是我想要的

方法调用的确可以, 但是我的情况类似于:

private bool a = false;
private bool b = false;
private bool c = false;
...................

private bool i ;

if()
  i = ref a;
else if()
 i = ref b;
else
 i = ref c;

i = true;

不希望再通过函数调用来完成。 很头疼

jewelry:

我不能说解决这个问题,我只是来说说我的理解:)

下面这段汇编作的事情很简单,就是下面的c#代码的编译结果

############# CODE ###############

       static void Main(string[] args)
       {
           bool input1 = true;
           bool input2 = true;

           changeValueByRef(ref input1);
           Console.WriteLine("1. Input is: {0}",input1);

           changeValueByPassin(input1);
           Console.WriteLine("2. Input is: {0}",input1);

           changeValueByPassin(input2);
           Console.WriteLine("3. Input is: {0}",input2);

           Console.Read();
       }
       static void changeValueByRef(ref bool b)
       {
           b ^= true;
       }
       static void changeValueByPassin(bool b)
       {
           b ^= true;
       }

########## IL ASM ###############

private static void Main(string[] args);

.maxstack 2
.locals (bool V_0, bool V_1)
L_0000: ldc.i4.1
L_0001: stloc.0
L_0002: ldc.i4.1
L_0003: stloc.1
L_0004: ldloca.s V_0
L_0006: call Class1.changeValueByRef
L_000b: ldstr "1. Input is: {0}"
L_0010: ldloc.0
L_0011: box bool
L_0016: call Console.WriteLine
L_001b: ldloc.0
L_001c: call Class1.changeValueByPassin
L_0021: ldstr "2. Input is: {0}"
L_0026: ldloc.0
L_0027: box bool
L_002c: call Console.WriteLine
L_0031: ldloc.1
L_0032: call Class1.changeValueByPassin
L_0037: ldstr "3. Input is: {0}"
L_003c: ldloc.1
L_003d: box bool
L_0042: call Console.WriteLine
L_0047: call Console.Read
L_004c: pop
L_004d: ret

注意,里面如果是ref的方式调用,

L_0004: ldloca.s V_0
L_0006: call Class1.changeValueByRef

如果是pass by value,

L_001b: ldloc.0
L_001c: call Class1.changeValueByPassin

or

L_0031: ldloc.1
L_0032: call Class1.changeValueByPassin

这里的ldloc.0和ldloc.1是本地变量,
这说明,两者的压栈方式不同,所以导致了调用方式不同,
那么,具体使用栈里面的东西的函数是什么样的呢?
耐心的看下去,

$$$$$$$$$$$$$$$$ PASS IN $$$$$$$$$$$$$$$$

private static void changeValueByPassin(bool b);

.maxstack 2
L_0000: ldarg.0
L_0001: ldc.i4.1
L_0002: xor
L_0003: starg.s b
L_0005: ret

$$$$$$$$$$$$$$$$$ BY REF $$$$$$$$$$$$$$

private static void changeValueByRef(ref bool b);

.maxstack 3
L_0000: ldarg.0
L_0001: dup
L_0002: ldind.i1
L_0003: ldc.i4.1
L_0004: xor
L_0005: stind.i1
L_0006: ret

两者最大的不同就是,后者使用ldind.i1来获取可以进行操作计算的值
并且,还把这个值保存了回去:stind.i1, 当然,需要这么做必须dup一下
传入的参数--那个可爱的引用地址,

获取数据的方式一个是直接使用栈顶数值作计算,一个是使用载入内存所指向
的数值并计算,两者自然不同:)

这么废话,不知道大家看懂没有,我只是初步的解释一下,
抛砖引玉:)



最新评论


hegara

2004-09-03 17:51

蛮好



chsoft

2004-09-13 01:08

呵呵,也来我这里看看吧,互相链接把
chsoft的小杂烩@chsoft.yculblog.com


评论 / 个人网页 / 扔小纸条
*昵称

已经注册过? 请登录

Email
网址
*评论