标签: cil

堆栈的目的是什么?我们为什么需要它?

所以我现在正在学习MSIL来学习调试我的C#.NET应用程序.

我一直想知道:堆栈的目的是什么?

只是把我的问题放在上下文中:
为什么从内存转移到堆栈或"加载?" 另一方面,为什么会从堆栈转移到内存或"存储"? 为什么不将它们全部放在内存中?

  • 是因为它更快吗?
  • 是因为它基于RAM吗?
  • 为了效率?

我正在努力掌握这一点,以帮助我更深入地理解CIL代码.

.net c# vb.net cil .net-assembly

316
推荐指数
5
解决办法
2万
查看次数

你在MSIL中可以做些什么,你不能用C#或VB.NET做什么?

用.NET语言编写的所有代码都编译为MSIL,但是只有使用MSIL才能直接执行特定的任务/操作吗?

让我们在MSIL中比C#,VB.NET,F#,j#或任何其他.NET语言更容易完成.

到目前为止我们有这个:

  1. 尾递归
  2. 通用Co/Contravariance
  3. 重载仅在返回类型上有所不同
  4. 覆盖访问修饰符
  5. 有一个不能从System.Object继承的类
  6. 过滤的异常(可以在vb.net中完成)
  7. 调用当前静态类类型的虚方法.
  8. 获取值类型的盒装版本的句柄.
  9. 做一个尝试/错误.
  10. 使用禁用名称.
  11. 为值类型定义自己的无参数构造函数.
  12. 使用raise元素定义事件.
  13. CLR允许一些转换,但C#不允许转换.
  14. 做一个非main()方法作为.entrypoint.
  15. 直接使用本机int和本机unsigned int类型.
  16. 玩瞬态指针
  17. MethodBodyItem中的emitbyte指令
  18. 抛出并捕获非System.Exception类型
  19. 继承枚举(未验证)
  20. 您可以将字节数组视为(4x更小)整数数组.
  21. 您可以使字段/方法/属性/事件具有相同的名称(未验证).
  22. 您可以从自己的catch块分支回try块.
  23. 您可以访问famandassem访问说明符(protected internal是fam assem)
  24. 直接访问<Module>类以定义全局函数或模块初始值设定项.

.net c# clr cil

161
推荐指数
13
解决办法
9231
查看次数

为什么C#编译器会将此变换!=比较,就像它是>比较一样?

我有机会发现C#编译器会改变这个方法:

static bool IsNotNull(object obj)
{
    return obj != null;
}
Run Code Online (Sandbox Code Playgroud)

...进入这个CIL:

.method private hidebysig static bool IsNotNull(object obj) cil managed
{
    ldarg.0   // obj
    ldnull
    cgt.un
    ret
}
Run Code Online (Sandbox Code Playgroud)

...或者,如果您更喜欢查看反编译的C#代码:

static bool IsNotNull(object obj)
{
    return obj > null;   // (note: this is not a valid C# expression)
}
Run Code Online (Sandbox Code Playgroud)

怎么把它!=翻译成" >"?

c# il cil binary-operators notnull

147
推荐指数
1
解决办法
5384
查看次数

Java的虚拟机和CLR

作为MSIL和Java字节码之间的差异问题的一种跟进,Java虚拟机的工作方式(主要)差异或相似之处是什么?.NET Framework 公共语言运行时(CLR)有效吗?

还有,是 .NET框架 CLR是"虚拟机"还是没有虚拟机的属性?

.net java cil bytecode vm-implementation

136
推荐指数
4
解决办法
4万
查看次数

为什么这个(null ||!TryParse)条件导致"使用未分配的局部变量"?

以下代码导致使用未分配的局部变量"numberOfGroups":

int numberOfGroups;
if(options.NumberOfGroups == null || !int.TryParse(options.NumberOfGroups, out numberOfGroups))
{
    numberOfGroups = 10;
}
Run Code Online (Sandbox Code Playgroud)

但是,这段代码工作正常(但ReSharper说这= 10是多余的):

int numberOfGroups = 10;
if(options.NumberOfGroups == null || !int.TryParse(options.NumberOfGroups, out numberOfGroups))
{
    numberOfGroups = 10;
}
Run Code Online (Sandbox Code Playgroud)

我错过了什么,还是编译器不喜欢我||

我把它缩小到dynamic导致问题(options在上面的代码中是一个动态变量).问题仍然存在,为什么我不能这样做

此代码无法编译:

internal class Program
{
    #region Static Methods

    private static void Main(string[] args)
    {
        dynamic myString = args[0];

        int myInt;
        if(myString == null || !int.TryParse(myString, out myInt))
        {
            myInt …
Run Code Online (Sandbox Code Playgroud)

c# compiler-construction cil dynamic c#-4.0

96
推荐指数
3
解决办法
2628
查看次数

简单的基准测试表现奇怪

昨天我发现了Christoph Nahr的一篇题为".NET Struct Performance"文章,文章 对几种语言(C++,C#,Java,JavaScript)进行了基准测试,为一种增加两个点结构(double元组)的方法.

事实证明,C++版本需要大约1000ms来执行(1e9次迭代),而C#在同一台机器上不能低于~3000ms(并且在x64中表现更差).

为了自己测试,我采用了C#代码(并略微简化为仅调用参数通过值传递的方法),并在i7-3610QM机器(3.1Ghz boost for single core),8GB RAM,Win8上运行. 1,使用.NET 4.5.2,RELEASE构建32位(x86 WoW64,因为我的操作系统是64位).这是简化版本:

public static class CSharpTest
{
    private const int ITERATIONS = 1000000000;

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    private static Point AddByVal(Point a, Point b)
    {
        return new Point(a.X + b.Y, a.Y + b.X);
    }

    public static void Main()
    {
        Point a = new Point(1, 1), b = new Point(1, 1);

        Stopwatch sw = Stopwatch.StartNew();
        for (int i = 0; i < ITERATIONS; i++) …
Run Code Online (Sandbox Code Playgroud)

c# performance benchmarking cil

96
推荐指数
3
解决办法
5295
查看次数

在"k + = c + = k + = c;"中是否有对内联运算符的解释?

以下操作的结果是什么解释?

k += c += k += c;
Run Code Online (Sandbox Code Playgroud)

我试图理解以下代码的输出结果:

int k = 10;
int c = 30;
k += c += k += c;
//k=80 instead of 110
//c=70
Run Code Online (Sandbox Code Playgroud)

目前我正在努力理解为什么"k"的结果是80.为什么分配k = 40不起作用(实际上Visual Studio告诉我该值没有在其他地方使用)?

为什么k 80而不是110?

如果我将操作拆分为:

k+=c;
c+=k;
k+=c;
Run Code Online (Sandbox Code Playgroud)

结果是k = 110.

我试图通过CIL查看,但是我在解释生成的CIL方面并没有那么深刻,也无法得到一些细节:

 // [11 13 - 11 24]
IL_0001: ldc.i4.s     10
IL_0003: stloc.0      // k

// [12 13 - 12 24]
IL_0004: ldc.i4.s     30
IL_0006: stloc.1      // c

// [13 13 - 13 30]
IL_0007: ldloc.0      // …
Run Code Online (Sandbox Code Playgroud)

c# cil compound-assignment

88
推荐指数
3
解决办法
6116
查看次数

在MSIL方法中hidebysig的目的是什么?

使用ildasm和C#程序,例如

static void Main(string[] args)
{

}
Run Code Online (Sandbox Code Playgroud)

得到:

.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       2 (0x2)
  .maxstack  8
  IL_0000:  nop
  IL_0001:  ret
} // end of method Program::Main
Run Code Online (Sandbox Code Playgroud)

hidebysig构造有什么作用?

cil

86
推荐指数
2
解决办法
2万
查看次数

为什么!0是Microsoft中间语言(MSIL)中的一种类型?

在许多MSIL列表中,我观察到以下内容:

System.Nullable`1<!0> etc ...
Run Code Online (Sandbox Code Playgroud)

要么

class !0 etc ...
Run Code Online (Sandbox Code Playgroud)

!0在这些情况下,这意味着什么?

.net c# cil

86
推荐指数
2
解决办法
4200
查看次数

动态替换C#方法的内容?

我想要做的是改变C#方法在调用时的执行方式,这样我就可以编写如下内容:

[Distributed]
public DTask<bool> Solve(int n, DEvent<bool> callback)
{
    for (int m = 2; m < n - 1; m += 1)
        if (m % n == 0)
            return false;
    return true;
}
Run Code Online (Sandbox Code Playgroud)

在运行时,我需要能够分析具有Distributed属性(我已经可以做)的方法,然后在函数体执行之前和函数返回之后插入代码.更重要的是,我需要能够在不修改调用Solve的代码的情况下或在函数的开头修改代码(在编译时;在运行时这样做是目标).

目前我尝试了这段代码(假设t是Solve存储的类型,m是Solve的MethodInfo):

private void WrapMethod(Type t, MethodInfo m)
{
    // Generate ILasm for delegate.
    byte[] il = typeof(Dpm).GetMethod("ReplacedSolve").GetMethodBody().GetILAsByteArray();

    // Pin the bytes in the garbage collection.
    GCHandle h = GCHandle.Alloc((object)il, GCHandleType.Pinned);
    IntPtr addr = h.AddrOfPinnedObject();
    int size = il.Length;

    // Swap the method.
    MethodRental.SwapMethodBody(t, m.MetadataToken, …
Run Code Online (Sandbox Code Playgroud)

c# methods swap cil assemblies

85
推荐指数
10
解决办法
5万
查看次数