高中生题库网(www.bjmy2z.cn)内容涵盖语文/数学/英语/政治/历史/地理/物理/化学/生物各门学科;各类知识点/试卷/习题/视频应有尽有,作文,听力,阅读专项突破,集合了各地的高考题和模拟考试题,可以让你孩子对于即将到来的高考有更加充足的准备!
关键词不能为空

当前您在: 主页 > 英语 >

读懂IL代码就这么简单

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

-

读懂IL代码就这么简单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代码就这么简单的相关文章

  • 爱心与尊严的高中作文题库

    1.关于爱心和尊严的作文八百字 我们不必怀疑富翁的捐助,毕竟普施爱心,善莫大焉,它是一 种美;我们也不必指责苛求受捐者的冷漠的拒绝,因为人总是有尊 严的,这也是一种美。

    小学作文
  • 爱心与尊严高中作文题库

    1.关于爱心和尊严的作文八百字 我们不必怀疑富翁的捐助,毕竟普施爱心,善莫大焉,它是一 种美;我们也不必指责苛求受捐者的冷漠的拒绝,因为人总是有尊 严的,这也是一种美。

    小学作文
  • 爱心与尊重的作文题库

    1.作文关爱与尊重议论文 如果说没有爱就没有教育的话,那么离开了尊重同样也谈不上教育。 因为每一位孩子都渴望得到他人的尊重,尤其是教师的尊重。可是在现实生活中,不时会有

    小学作文
  • 爱心责任100字作文题库

    1.有关爱心,坚持,责任的作文题库各三个 一则150字左右 (要事例) “胜不骄,败不馁”这句话我常听外婆说起。 这句名言的意思是说胜利了抄不骄傲,失败了不气馁。我真正体会到它

    小学作文
  • 爱心责任心的作文题库

    1.有关爱心,坚持,责任的作文题库各三个 一则150字左右 (要事例) “胜不骄,败不馁”这句话我常听外婆说起。 这句名言的意思是说胜利了抄不骄傲,失败了不气馁。我真正体会到它

    小学作文
  • 爱心责任作文题库

    1.有关爱心,坚持,责任的作文题库各三个 一则150字左右 (要事例) “胜不骄,败不馁”这句话我常听外婆说起。 这句名言的意思是说胜利了抄不骄傲,失败了不气馁。我真正体会到它

    小学作文