分享
 
 
 

IL代码底层运行机制

王朝other·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

IL代码底层运行机制

IL代码底层运行机制

刘强

Cambest@sohu.com

2003年5月8日

大家都知道,和Java一样,C#也是基于堆栈的语言。也许对一般人来说,底层的运行细节并不是很重要;但了解这些,对我们理解、运用C#是很有帮助的。下面,我就通过一个很简单的例子来说明IL代码的底层运行机制,也许对你会有一些帮助。

我给出的例子表面上看是一个实现整数相减功能的函数;实际上,我也不知道究竟能够干什么。在实际当中,我们的程序当中会有很多种数据类型、引用类型,为了简便起见,我所给出的示例代码只用了一种数据类型,如下所示:

public int Sub(int i,int j)

{

int s;

int t = 0;

int r = 4;

s=i;

r =i – j;

r + =s + t;

return r;

}

这段代码很简单,任何学过C#的人都能看懂。首先,传入两个整型变量i和j,然后经过内部运算,返回一个整型值。函数体内定义了三个局部变量s,t,

r,分别用于保存自定义值以及结果。我们可以将它包装进一个类中,然后将它编译成.dll装配件。运用VS.NET自带的ildasm反汇编工具进行反汇编,我们得到如下IL代码:

.method

public hidebysig instance int32 Sub(int32 i,

int32 j) cil managed

{

// Code

size 22 (0x16)

.maxstack

3

.locals

init (int32 V_0, int32 V_1, int32 V_2, int32 V_3)

ldc.i4.0

stloc.1

ldc.i4.4

stloc.2

ldarg.1

stloc.0

ldarg.1

ldarg.2

sub

stloc.2

ldloc.2

ldloc.0

ldloc.1

add

add

stloc.2

ldloc.2

stloc.3

br.s

IL_0014

ldloc.3

ret

}

IL代码也可以由VS.NET自带的IL编译工具ilasm编译为.dll装配件或.exe可执行文件。

这里,我要对IL中出现的符号作一下简单解释。以点号’.’开头的标号为伪指示代码,只起指示作用,最终不会被JIT编译为本地可执行代码,如“.method”,“.locals”等。而不带点号’.’的标号为IL汇编代码,它们在运行时将会被JIT编译为本地可执行代码,如“ldarg.1”等。

每条语句究竟代表了什么样的操作,我们下面在详细讲解。注意:局部变量的下标从0开始,因此要注意我下面所说的“第零个局部变量”等的含义。

首先,让我们看一看函数体内的第一条语句:.maxstack

3。从其本身我们也可以猜出该语句说明堆栈的大小。暂且不表,且看下文。

第二句:.locals

init (int32 V_0, int32 V_1, int32 V_2, int32 V_3)

。V_0、V_1、V_2和我们在CS源程序中定义的局部变量s,t,r一一对应,我们大概也能猜到这一句是完成局部变量初始化工作的,但为什么在这里是四个呢?我们明明只定义了三个变量的。那么这由C#编译器自动维护的第四个变量有何作用?也暂且不表,先看下文。

ldc.i4.0

这条语句作用是在堆栈中载入常数,i4表示该常数为双字长的32位整型数,初始值为0。“ldc”可以理解为“load

constant”,加载常数。如图a,它完成的操作如同(top)<=0,top=top+1。

stloc.1

这条语句作用是将当前栈顶元素存入第一个局部变量。’1’表示操作对象为第一个局部变量。“stloc”可以理解为“store

to local”,保存局部变量。如图b,它完成的操作如同top=top-1,s<=(top)。

ldc.i4.4

这条语句完成的操作如同(top)<=4,top=top+1,如图c。

stloc.2

这条语句完成的操作如同top=top-1,t<=(top),如图d。

ldarg.1

ldarg.2

这两条语句作用是在堆栈中载入第一个参数(i)、第二个参数(j)(和局部变量不同,参数的指示下标从1开始)。它完成的操作如同

(top)<=i,top=top+1,(top)<=j,top=top+1,如图e。其中,“ldarg”可以理解为“load

argument”,加载参数。

sub

这条语句作用是将当前栈顶元素求反,再下加到第二个栈单元中,如图f。它完成的操作如同top=top-1,temp=

-(top),top=top-1,(top)=(top)+

temp,top=top+1。

top

0

top

top

4

top

top

j

i

top

i-j

(a)

(b)

(c)

(d)

(e)

(f)

stloc.2

这条语句作用是将当前栈顶元素存入第二个局部变量(r)。它完成的操作如同top=top-1,r<=(top),即r=i-j,如图

ldloc.2

ldloc.0

ldloc.1

这三条语句作用是分别将第二、第零个、第一个局部变量加载到堆栈上,如图h。“ldloc”可以理解为“load

local variable”,加载局部变量。

add

add

add的用发和sub一样,只不过不将当前栈顶元素求反,再下加到第二个栈单元中,连续操作两次。如图i、j。

stloc.2

将当前栈顶元素存入第二个局部变量。如图k。

ldloc.2

在堆栈中载入第二个局部变量(r),如图l。

top

top

r

top

top

r+s+t

top

s+t

r

top

t

s

r

(g) (h)

(i) (j)

(k) (l)

stloc.3

将当前栈顶元素存入第三个局部变量,亦即保存返回值,如图m所示。

br.s IL_0014

跳转到下一句(ldloc.3)。如图n所示。

ldloc.3

ret

将第三个局部变量(也即由编译器自动维护的变量)加载到堆栈上,然后返回,如图o。从这里我们也可以看出,1、第三个变量和返回值类型相同;2、扫尾后、返回前将第三个局部变量加载至堆栈。这可以让我们确定:第三个变量用于存储返回值。我们还要弄清楚为什么要专门分配一个局部变量来存储返回值,这一点在后面会有说明。

top

top

top

V_3

(m)

(n)

(o)

综观图a~o,我们回发现,整个函数过程所用到的最大栈数目就是3,这也就不难理解第一条语句

.maxstack 3 了。

现在,还有一点让人迷惑的是为什么要引入变量V_3?如上例中,倒数第二条指令ldloc.3

也可以由ldloc.2

代替,因为我们所要的结果就是存储在第二个变量r中的,这不是浪费空间嘛。要注意了,并不所有的返回值都保存在局部变量中的。

有可能我们将参数直接返回,或者将类成员变量返回,如:

public int Laxi(int x)

{

return x;

//直接将参数返回

}

或者是

int age;...

public int GetAge()

{

return age; //返回在类中定义的字段

}

或者是直接返回一个表达式:

public int GetInteger()

{

return age+4*6/2;

}

则必须进行这一步转换,以return

r为例:ldloc.x ->

stloc.y ->ldloc.y ->ret .

因为在以上三种情况当中,返回值都不存储在局部变量当中。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有