IL代码(中间语言代码)

原文链接

参考链接

IL常见指令

常见方法

Call,Calli,Callvirt

  • Call:常用于调用编译时就确定的方法,可以直接去元数据里找方法,如静态函数,实例方法,也可以call虚方法,不过只是call这个类型本身的虚方法,和实例的方法性质一样。另外,call不做null检测。

  • Calli: MSDN上讲是间接调用指针指向的函数。

  • Callvirt: 可以调用实例方法和虚方法,调用虚方法时以多态方式调用,不能调用静态方法。Callvirt调用时会做null检测,如果实例是null,会抛出NullReferenceException,所以速度上比call慢点。

加载(Id)和存储(st)

Idloc.0:

把索引为0的局部变量加载到计算栈中。

Id:load;loc:Local variable(局部变量);.0:表示索引。

  • ldstr = load string,
  • ldnull = load null,
  • ldobj = load object,
  • ldfld = load field,
  • ldflda = load field address,
  • ldsfld = load static field,
  • ldsflda = load static field address,
  • ldelem = load element in array,
  • ldarg = load argument,

ldc 则表示加载数值,如ldc.i4.0; .i[n]表示字节数,一个字节8位;i4四个字节就是int32类型;.0表示索引为0。

alt

关于后缀

  • .i[n]:[n]表示字节数,1个字节是8位,所以是8*n的int,比如i1, i2, i4, i8,i1就是int8(byte), i2是int16(short),i4是int32(int),i8是int64(long)。相似的还有.u1 .u2 .u4 .u8 分别表示unsigned int8(byte), unsigned int16(short), unsigned int32(int), unsigned int64(long);

  • .R4,.R8 表示的是float和double。

  • .ovf (overflow)则表示会进行溢出检查,溢出时会抛出异常;

  • .un (unsigned)表示无符号数;

  • .ref (reference)表示引用;

  • .s (short)表示短格式,比如说正常的是用int32,加了.s的话就是用int8;

  • .[n] 比如 .1,.2 等,如果跟在i[n]后面则表示数值,其他都表示索引。如 ldc.i4.1就是加载数值1到计算栈上,再如ldarg.0就是加载第一个参数到计算栈上。

ldarg要特别注意一个问题:如果是实例方法的话ldarg.0加载的是本身,也就是this,ldarg.1加载的才是函数的第一个参数;如果是静态函数,ldarg.0就是第一个参数。

与Id对应的就是st,可以理解为store(储藏),意思是把值从计算栈存到变量中去, ld相关的指令很多都有st对应的,比如stloc, starg, stelem(存储数组中的元素)等,

比较跳转指令,判断bool值

以b开头:beq, bge, bgt, ble, blt, bne

先把b去掉看看:

  • eq: equivalent with, == 等于
  • ge: greater than or equivalent with , >= 大于等于
  • gt: greater than , > 大于
  • le: less than or equivalent with, <= 小于等于
  • lt: less than, < 小于
  • ne: not equivalent with, != 不等于

这样是不是很好理解了,beq IL_0005就是计算栈上两个值相等的话就跳转到IL_0005, ble IL_0023是第一个值小于或等于第二个值就跳转到IL_0023。

以br(break)开头:br, brfalse, brtrue,

  • br是无条件跳转;
  • brfalse表示计算栈上的值为 false/null/0 时发生跳转;
  • brtrue表示计算栈上的值为 true/非空/非0 时发生跳转

还有一部分是c开头,算bool值的,和前面b开头的有点像:

  • ceq 比较两个值,相等则将 1 (true) 推到栈上,否则就把 0 (false)推到栈上
  • cgt 比较两个值,第一个大于第二个则将 1 (true) 推到栈上,否则就把 0 (false)推到栈上
  • clt 比较两个值,第一个小于第二个则将 1 (true) 推到栈上,否则就把 0 (false)推到栈上
全部评论

相关推荐

2025-12-06 01:10
已编辑
哈尔滨工程大学 Java
一面问的真细,二面不知为啥变双机位。9.29快手主站平时怎么学习&nbsp;AI&nbsp;的,国内外知名大模型,实习公司都用的什么大模型,怎么评估效果的java池化思想,线程池构造方法的核心参数,线程池中阻塞队列注意事项,submit方法参数和执行逻辑,shutdown和shutdownnow,核心线程允许过期吗threadlocal底层,为什么key是弱引用,key回收了再get或者set这个value会怎样aqs,如何保证公平性java代理java堆划分,新生代还有别的晋升老年代的情况吗,什么时候触发gc,gc失败抛什么异常,如何排查oom,导出dump命令redis数据结构,哪个底层是跳表,和其他数据结构对比布隆过滤器会出现大key问题吗,你咋实现的布隆过滤器你怎么实现redis分布式锁,可重入,续期聚簇索引非聚簇索引select语句会加锁吗,怎么实现的不加锁undolog&nbsp;redolog&nbsp;binlog怎么能让select加锁,update这个范围加的什么锁,update一条呢手撕简单01背包,接雨水10.10快手主站意图识别用的哪个大模型,走到意图和rag的比例,faq是点击的吗自然语言怎么识别的gap一年干啥了,转正怎么样没跟组里提意向吗,研究生研究方向是传统算法吗,会大模型微调吗注册场景为什么用布隆过滤器,原理分布式锁底层的key怎么拼的,value里是什么redis持久化zset底层mysql索引结构,一个表三个字段有主键唯一索引和没索引的字段会有几个b+树,聚簇索引非聚簇索引存的啥无手撕
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
01-15 20:52
黑皮白袜臭脚体育生:五宿大战是吧,死去的记忆还在攻击我
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务