我在尝试使用 Visual Studio 命令提示符(反)组装 dll 时遇到了困难,看起来不像我在 microsoft page 中看到的那么简单。
我正在以这些方式使用 ildasm:
ildasm myLibrary.dll output:MyLibrary.il
Run Code Online (Sandbox Code Playgroud)
我得到:无法打开“MyLibrary.il”进行输出。
我也试过完整路径:
ildasm directory\myLibrary.dll output:directory\MyLibrary.il
Run Code Online (Sandbox Code Playgroud)
我得到:指定的多个输入文件
使用 ildasm GUI 实际上有效,但是当我使用 ilasm 时:
ilasm myLibrary.il /dll
Run Code Online (Sandbox Code Playgroud)
我得到:无法打开 'myLibrary.il',当我使用完整路径时,我得到了同样的错误。
这里有什么问题?
我正在尝试生成一个足够智能的工具,以编程方式检查在不同时间在两个单独的机器上编译的相同C#代码生成的发行版本二进制文件,并得出结论,代码是相同的,同时能够获取任何代码更改(如果存在于用于生成这些二进制文件的c#代码.
我尝试过使用多种方法,但为了保持这种简短,我只会坚持最新的尝试.我在二进制文件上使用/ text选项运行ildasm并在文本中替换匿名字段等的GUID,但是当二进制文件来自不同的pc时,我发现ILDASM/text选项生成的文本被重新排序.源自相同代码但在不同机器上通过相同设置编译的二进制文件也出现严重重新排序.任何建议如何能够控制IL的重新排序将是非常感激的?
干杯
PS:任何可靠地实现这一目标的替代策略也是最受欢迎的.
我正在通过 C#(第 4 版)阅读 CLR 一书,不是作为 C# 的新手,而是作为了解该语言的人,试图提高我对 CLR 底层功能的掌握程度。
无论如何,在这本书中给出了一个例子 (pg127-131),当讨论值类型的装箱/拆箱时,它以调用 Console.WriteLine 结束,值类型被连接到作为参数传递的字符串。
这本书解释了装箱和拆箱/复制操作会导致开销,这是我已经知道的,但随后说明可以通过在传入的值类型上运行 .ToString() 来优化示例。
我创建了一个示例程序并编译它,然后使用 ILDASM 来检查它生成的 IL。带有 ToString 的版本本质上是相同的,但用对 ToString 的“调用”替换了“box”指令(没有震惊)。
我在 100000 次运行的循环中对代码进行了基准测试,并且没有区别(它波动哪个更快)。我意识到在进行基准测试(缓存等)时其他因素会起作用,但通过本书解释它的方式,我曾期望即使在幼稚的基准测试中避免“box”指令时也会看到显着差异。
难道只是调用一个函数并没有好多少?是否在 ToString 中进行了拳击操作,使好处无效并且这本书是错误的?有人可以对此有所了解吗?
作为参考,这里有两个 ILDASM 读数:
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 24 (0x18)
.maxstack 2
.locals init (int32 V_0)
IL_0000: ldc.i4.4
IL_0001: stloc.0
IL_0002: ldloc.0
IL_0003: box [mscorlib]System.Int32
IL_0008: ldstr "."
IL_000d: call string [mscorlib]System.String::Concat(object,
object)
IL_0012: call void [mscorlib]System.Console::WriteLine(string)
IL_0017: ret
} …Run Code Online (Sandbox Code Playgroud) 我有以下程序来添加值.当我在main方法中调用Add方法调用并查看ILDASM.EXE时,Maxstack大小为2.并且在取消注释后,maxstack大小变为4.
为什么在Main方法的情况下所有变量都不会进入堆栈,因为堆栈大小仅为2,而在Add方法调用的情况下,每个变量都进入堆栈?这是主要方法计算内部逐个发生的情况,因此一次只需要两个变量.
请清除我的困惑.
static void Main(string[] args)
{
int x = 2;
int y = 3;
int a = 4;
int b = 5;
int c = 6;
Console.WriteLine(x + y + a + b + c);
Console.WriteLine(Add(10, 20, 30, 40));
Console.ReadLine();
}
static int Add(int x, int y, int z, int a)
{
return x + y + z + a;
}
Run Code Online (Sandbox Code Playgroud) 我现在特别想了解IL代码和C#内部,我写了一个简单的c#hello world程序,代码是:
using System;
class Program
{
public static void Main()
{
Console.WriteLine("Hello World");
}
}
Run Code Online (Sandbox Code Playgroud)
这里是为Program类的构造函数生成的IL :
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: ret
} // end of method Program::.ctor
Run Code Online (Sandbox Code Playgroud)
我无法理解是什么的意义和目的specialname和rtspecialname或有什么用他们的?
System.Reflection不支持(AFAIK)反映程序集中的全局方法.在程序集级别,我必须从根类型开始.
我的编译器可以使用全局方法生成程序集,而我的标准引导程序库是一个包含一些全局方法的DLL.我的编译器使用System.Reflection在编译时导入程序集元数据.似乎我依赖System.Reflection,全局方法不可能.最干净的解决方案是将我的所有标准方法转换为类静态方法,但重点是,我的语言允许全局方法,而CLR支持它,但System.Reflection留下了空白.
ildasm显示全局方法就好了,但我认为它不使用System.Reflection本身并直接进入元数据和字节码.
除了System.Reflection之外,是否有人知道我可以使用的任何其他第三方反射或反汇编库(假设我最终会将我的编译器释放为免费的,BSD许可的开源).
解决:除了我所知,没有差距.谢谢你指出GetModules,伙计们!
我正在尝试编译器性能.我有一小段代码,只有一些浮点乘法和加法.代码在循环中执行数百万次.我试图用C++,c#,java,perl,python编译代码......然后我在测量执行时间的同时运行结果.
我对c#性能非常不满意.我的c#代码比同等的C++或java慢约60%.我相信,我的实验中肯定有一个错误.我想反汇编生成的二进制文件来了解原因.
MSIL代码有这样的选项吗?是否可以在机器指令级别检查c#JIT编译器的结果(x86指令,而不是MSIL指令)?
更新
代码(u,v,g*是double; steps是整数)
stopwatch.Start();
for (int i = 0; i < steps; i++)
{
double uu = g11 * u + g12 * v;
v = g21 * u + g22 * v;
u = uu;
}
stopwatch.Stop();
Run Code Online (Sandbox Code Playgroud) 我一直在玩ILDasm,并注意到:
反编译C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Runtime.dll (36KB)只返回清单文件.反编译C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETCore\v4.5\System.Runtime.dll (114KB)返回清单和程序集中的所有类型.
反编译C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETCore\v4.5\mscorlib.dll (38KB)只返回清单文件,反编译C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.dll (5171KB)返回清单和程序集中的所有类型.
我找不到有关为什么以这种方式构建组件的任何信息.
两个汇编目录有什么区别,为什么在文件系统上有两个副本?为什么两个程序集中的类型都重复?System.Runtime和mscorlib都包含大多数相同的类型.
我最近升级到VS 2017并卸载了之前的VS 2015。
但是,当我尝试构建和编译我的项目时,我不断收到错误:
Microsoft.Build.Utilities.ToolLocationHelper could not find ildasm.exe
该项目使用 C# 的非托管导出 - https://www.nuget.org/packages/UnmanagementExports
我不明白为什么会出现此消息,而谷歌搜索却没有显示任何内容。我已确保目标框架相同 >> 4.5.2。但什么也不会建立!
但我只能找到以下目录:
C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools
请帮忙,谢谢
我正在尝试针对 .NetCore3.1 控制台应用程序运行作为 Visual Studio 2019 的一部分安装的 ildasm(中级语言反汇编程序)。
使用 Visual Studio 2019 的开发人员命令提示符并运行以下命令
ildasm.exe D:\DotNet\IntroductionToCsharp\IntroductionToCsharp\bin\Debug\netcoreapp3.1\IntroductionToCsharp\bin\Debug\netcoreapp3.1\IntroductionToCsharp.exe
但出现以下错误:
'D:\DotNet\IntroductionToCsharp\IntroductionToCsharp\bin\Debug\netcoreapp3.1\IntroductionToCsharp.exe' 没有有效的 CLR 标头,无法反汇编

注意:在非 Core (.Net Framework 4.x) exe 上运行相同的命令可以正常工作。也许在 .Net Core 中查看 IL 需要一些特殊的东西?