关键词不能为空

当前您在: 主页 > 英语 >

读懂IL代码就这么简单

作者:高考题库网
来源:https://www.bjmy2z.cn/gaokao
2021-03-03 12:38
tags:

-

2021年3月3日发(作者:诊疗所)


一前言





感谢


@


冰麟轻武



指出文章的错误之处,现已更正





对于


IL


代 码没了解之前总感觉很神奇,初一看完全不知所云,只听高手们说,了解


IL

< p>
代码你能更加清楚的知道你的代码是如何运行相互调用的,此言一出不明觉厉。


然后开始接触


IL


,了解了一段 时后才发现原来读懂


IL


代码并不难。进入正题





1.1



什么是


IL





IL


是< /p>


.NET


框架中中间语言



Intermediate Language



的 缩写。使用


.NET


框架


提供的


编译器


可以直接将源程序编译为


.exe



.dll


文件,但此时编译出来的程序代 码并不



CPU


能直接执行的机器代码 ,而是一种中间语言


IL



Inter mediate Language


)的代


< br>(


来源百度


)



1.2


为什么要了解


IL







在很多时候不明白代码是如何操作时就可以通过


IL


指令来解释,比如,装箱,拆箱


是否只是听别人说或者书上讲是怎么怎么实现的 ,自己是否证实过呢?了解


IL


指令你可清

楚看到是每一步是如何处理的





1.3



怎么学


IL






世上有个定律叫

< br>“


二八定律




80%


的功能,只要用


20%


的技术就可以完成,但要完


成另外


20%

可能就需要


80%


技术了,对于


I L


代码也是如此,有


200


多个指令, 我们只


需要用到其


20%


的指令就可以 解决我们


80%


的问题了,所以我不会写太多,只是让大家


能看懂普通的程序代码编译成


IL


代码后就 行了,还有就是要多看,


IL


代码的每一条指令都


是特定的意思,看得多了自然就懂了,当对自己代码有疑问时尝试看看它对应的


IL


代码,


也许你会了解得更多。





如何查看


IL


代码





2.1


步骤





1


编写代码并编译通过






2


< /p>


找到源文件的


obj


文件下的

< p>
.exe


文件





3



导 入到


ILDasm


中反编译成


IL


代码



上图



1 -2






























3



导 入到


ILDasm























ILDasm


中图标含义










如何读


IL(


大致了解


)




以上步骤完成后我们就可以看到代 码被编译后的


IL


代码,


以下部份将会 对每一条


IL



令做详细的解释





C#


代码



1











static



void


Main(


string


[] args)


2











{


3















int


i =


1


;


4















int


j =


2


;


5















int


k =


3


;


6















ine(i+j+


k);


7











}




IL


代码



// Call


Stack


是一个局部变量列表,用于存储


.locals init (int32 V_0,int32


V_1,int32 V_2)


初始化后的参数



V_0,V_1,V_2


// Evaluation Stack


是一个栈


ldc.i4.2


这种指令都会先把值压入栈中等待操作




在第四段时大家可以理解得更清楚一点




1




.method


private


hidebysig


static



void




Main(


string


[] args) cil managed



2



{



3





.entrypoint



//


程序入口




4





// Code size








19 (0x13)




5





.maxstack



3




//< /p>


定义函数代码所用堆栈的最大深度,


也可理解为

< br>Call Stack


的变量个数





6





//


以下 我们把它看做是完成代码中的初始化




7





.locals init (int32 V_0,int32 V_1,int32 V_2)


//


定义



int


类型参数



V_0,V_1,V_2


(此时已经把


V_0,V_1,V_2


存入了


Call Stack


中)




8





IL_0000:



nop


//



No Operation


没有任何操作,我们也不用管它





9





IL_0001:



ldc.i4.


1






//< /p>


加载第一个变量









(压入


Evaluation


Stack


中)





10





IL_0002:



stloc.


0







//




赋值给


Call Stack


中第


0


个位置


(V_0)






11





IL_0003:



ldc.i4.


2






//< /p>


加载第二个变量









(压入


Evaluation


Stack


中)




12





IL_0004:



stloc.


1







//




赋值给


Call Stack


中第


1


个位置


(V_1)



13





IL_0005:



ldc.i4.


3






//< /p>


加载第三个变量










(


压入


Evaluation Stack



)



14





IL_0006:



stloc.


2







//





赋值给


Call Stack


中第


2


个位置


(V_2 )



15








16






//


上面代码初始化完成后要开始输 出了,所要把数据从


Call Stack


中取出



17




18





IL_0007:



ldloc.


0







//



Call Stack


中位置为


0


的元素


(V _0)


的值


(


的值

)




(


相当于


Copy


一份值


Call St ack



V_0


的值。


V_0


本身的值是不变的


)



19





IL_0008:



ldloc.


1







//



Call Stack


中位置为


1


的元素


(V _1)


的值


(


的值

)







(


同上


)



20





IL_0009:



add










//


做加法操作



21





IL_000a:



ldloc.


2







//


取出


Call Stack


中位置为


2


的元素


(V_2)


的值


(


的值


)



22





IL_000b:



add










//


做加法操作



23





IL_000c:



call








void


[mscorlib]e::WriteLine(int32)


//



用输出方法



24





IL_0011:



nop


25





IL_0012:



ret










//


即为




return



标记



返回值



26


}


// end of method Program::Main





指令详解



.maxstack:


评估堆栈


(Evaluation Stack)


可容纳数据项的最大个数



.locals init (int32 V_0,int32


V_1,int32 V_2)


:定义变量并存入


Call Stack





nop:



No Operation


没有任何操作,我们也不用管它,



ldstr.:



Load String


把字符串加压入


Evaluation Stack




stloc.


:把


Evaluation Stack


中的值弹出赋值到


Call Stack




ldloc.:



Call Stac k


中指定位置的值取出


(copy)


存 入



Evaluation Stack






以上两条


指令为相互的操作


stloc


赋值,


ldloc

< br>取值



call:



调用指定的方法



ret:



return



标记返回





每一句


IL


代码都加了注释后,


是不是觉得


IL


代码其实并不难呢,


因为它的每一条指令


都是固定的,你只要记住了,看

IL


代码就比较轻松了。






如何读


I L(


深入了解


)


4.1


提出问题





有了上面的一点


IL


基础后,现在我们 来深入一点点,





有如下几个问题:





1





ldc.i4.1


这一指定加载



“i”


这个变量后并没有马上赋值给


Call Stack


中的元


素,而是要执行


stloc.0


后才赋值,那没赋值前是存在哪里的呢?





2 ldloc.0



把元素取出来后,存在哪里的?





3 add


操作完成后值存在哪里?



4.2


概念引入





Managed Heap


:



這是動態配置(


Dynamic Allocation


)的記憶體,由



Garbage


Collector



GC


)在執行時自動管理,整個



Process


共用一個






Managed Heap(


我理解为托管堆,存储引用类型的 值


)






Evaluation Stack


:


這是由


.NET CLR


在執行時自動管理的記憶體,每個



Thread


都有自己專屬的



Evaluation Stack(


我理解为类似一个临时存放值类型数据的线程栈


)




Call Stack


:


這是由


.NET CLR


在執行時自動管理的記憶體,每個



Thread


都有自


己專屬的



Call Stack


。每呼叫一次



method


,就會使得



Call Stack


上多了一個



Record






Frame


;呼叫完畢之後,此



Record Frame


會被丟棄


(


我理解为一个局部变量表,用于存



.locals init(int32 V_0)


指令的参数值如:


V_0


)



4.3


IL


指令详解



对三个名词做解释后现在我们再来仔细看看执行


IL


指令时 ,对应的变量是如何存放的



IL_0001: ldc.i4.1 //


加载第一个变量


i



首先对


ldc.i4.1


做下细解:变量的值为


1



IL


指令就是


ldc.i4.1


,


变量值为


2



IL



令就是

ldc.i4.2


,依此类推一直到


ldc.i4.8



当为


-1



IL


指令为


ldc.i4.M1,< /p>


当超过


8


时就是一个统一指令

< p>
ldc.i4.S




IL_0001: ldc.i4.1 //


加载第一个变量


i



当执行这一条指令时会把变量


i


的值压入


Evaluation Stack


中做临时存储





IL_0002: stloc.0 //



i


赋值给


Call Stack


中第


0


个位置



当执行这一条指信时会把


Evaluation Stack


中的


i


弹出赋值给


Call Stack


中的 第


0


个位






IL_0007: ldloc.0 //


取出


Call Stack


位置为


0


的元素


(i)



当执行这条指令时会将


Call Stack


中的位置为


0


的 元素的值取出


(copy)


压入


Eva luation


Stack


等待做加法的指令


Add






IL_000b: add //


做加法操作





add


这一操作完成后,会把结果存 在


Evaluation Stack


中等待下一步的指令操作



4.4


问题回答


-


-


-


-


-


-


-


-



本文更新与2021-03-03 12:38,由作者提供,不代表本网站立场,转载请注明出处:https://www.bjmy2z.cn/gaokao/699960.html

读懂IL代码就这么简单的相关文章

  • 余华爱情经典语录,余华爱情句子

    余华的经典语录——余华《第七天》40、我不怕死,一点都不怕,只怕再也不能看见你——余华《第七天》4可是我再也没遇到一个像福贵这样令我难忘的人了,对自己的经历如此清楚,

    语文
  • 心情低落的图片压抑,心情低落的图片发朋友圈

    心情压抑的图片(心太累没人理解的说说带图片)1、有时候很想找个人倾诉一下,却又不知从何说起,最终是什么也不说,只想快点睡过去,告诉自己,明天就好了。有时候,突然会觉得

    语文
  • 经典古训100句图片大全,古训名言警句

    古代经典励志名言100句译:好的药物味苦但对治病有利;忠言劝诫的话听起来不顺耳却对人的行为有利。3良言一句三冬暖,恶语伤人六月寒。喷泉的高度不会超过它的源头;一个人的事

    语文
  • 关于青春奋斗的名人名言鲁迅,关于青年奋斗的名言鲁迅

    鲁迅名言名句大全励志1、世上本没有路,走的人多了自然便成了路。下面是我整理的鲁迅先生的名言名句大全,希望对你有所帮助!当生存时,还是将遭践踏,将遭删刈,直至于死亡而

    语文
  • 三国群英单机版手游礼包码,三国群英手机单机版攻略

    三国群英传7五神兽洞有什么用那是多一个武将技能。青龙飞升召唤出东方的守护兽,神兽之一的青龙。玄武怒流召唤出北方的守护兽,神兽之一的玄武。白虎傲啸召唤出西方的守护兽,

    语文
  • 不收费的情感挽回专家电话,情感挽回免费咨询

    免费的情感挽回机构(揭秘情感挽回机构骗局)1、牛牛(化名)向上海市公安局金山分局报案,称自己为了挽回与女友的感情,被一家名为“实花教育咨询”的情感咨询机构诈骗4万余元。

    语文