c# - ref 参数的 IL 差异
问题描述
我试图了解通过引用传递的参数和值在 IL 级别处理的方式之间的区别。
这是C#中的两种方法
public static void TestRef(ref int x)
{
x++;
}
public static void Test(int x)
{
x++;
}
值传递的 IL 在下面,我知道它加载 arg,然后是 int 常量 1 并将其添加并将其填充回堆栈中。
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldc.i4.1
IL_0003: add
IL_0004: starg.s x
IL_0006: ret
通过引用传递的方法的 IL:
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldarg.0
IL_0003: ldind.i4
IL_0004: ldc.i4.1
IL_0005: add
IL_0006: stind.i4
IL_0007: ret
我不明白为什么有这两个ldarg.0
陈述。我假设 IL_0002/3 只是加载参数地址,然后是该地址的参数值。
但那么 IL_0001 呢?是不是跟左边有关系x =x+1
?
解决方案
at 加载的地址IL_0001: ldarg.0
将被 at 的存储操作消耗IL_0006: stind.i4
。
msdn 告诉我们有关stind.i4
操作码的信息:
堆栈过渡行为,按顺序,是:
一个地址被压入堆栈。
一个值被压入堆栈。
值和地址从堆栈中弹出;该值存储在地址中。
推荐阅读
- loops - 如何在整个二维数组中找到最大值(处理)
- vue.js - 调用父Vue组件的方法
- typescript - 在 ES6 模块中扩展对象原型给出了“对象”类型上不存在的属性
- java - 在 Java 中打印一个左三角形 - 程序可以工作,但为什么呢?
- sqlite - 如何将表从 SQL 中的 .db 文件导出到 Excel 和 csv
- udp - netcat 端口 1900 没有返回响应
- javascript - GET 没有给我新数据
- node.js - req.user 在 Passport + Express + Node 中未使用谷歌策略定义
- java - 启动 Anypoint Studio 时缺少错误日志
- php - DOMDocument::loadHTML(): htmlParseEntityRef: 实体中没有名称