【问题标题】:Generating big files in .NET在 .NET 中生成大文件
【发布时间】:2013-05-18 13:43:25
【问题描述】:

我想问一下关于 .NET 可执行文件的两件事:

  1. .NET 可执行文件是 PE 格式。这是否意味着CIL编译器生成的地址是从文件的开头(address+size_of_headers)?还是这些地址仅在内存中执行图像时使用?

  2. 是否可以(通过 CIL 编译器)生成大小大于 4GB 的可执行文件?如果是,如果编译器必须从文件末尾调用方法或分支到超过 4GB 限制的字节,编译器会做什么?

确实,我从未见过任何大于 4GB 的 C# 可执行文件,我只是好奇。

【问题讨论】:

  • “CIL编译器生成的地址”你说的是什么地址?
  • 输出代码中操作码后面的地址。
  • 哪个操作码?每个操作码都有自己的格式。
  • br, br_s, brture, brtrue_s 操作码

标签: c# .net compiler-construction branch cil


【解决方案1】:

我认为您将执行 CIL 的工作方式与执行本机代码的工作方式混淆了。

使用 CIL,可执行文件中的代码不会实际执行。通常(使用桌面 CLR 而没有 ngen)CLR 读取 CIL 并动态生成实际的可执行代码(这就是为什么 CLR 的这一部分被称为“即时编译器”)。

call 这样的CIL 操作码使用标记来引用方法和其他成员。在生成的本机代码中,这些被翻译成该方法的本机代码的地址。

br 这样的操作码包含相对于下一条 CIL 指令的偏移量,它们只能在当前方法内跳转。在 x86 上,它们被编译为类似 jne 的指令,其中包含相对于下一条 x86 指令的偏移量。

但方法的元数据在MethodDef 表中进行了描述,该表包含对该方法的IL 流的引用作为4 字节Relative Virtual Address(并且文件的其他部分也使用了RVA)。我认为这意味着可执行文件的大小实际上不能超过 4 GB。

我试图通过使用 Reflection.Emit 创建一个大型可执行文件来验证这一点。但是我在 8 GB RAM 的系统上能做的最好的事情就是创建一个 1.5 GB 的大文件(这已经使计算机由于交换而无法使用)。

【讨论】:

  • 好的。因此,假设方法代码大于 4GB。 CIL 会做什么?
猜你喜欢
  • 2010-11-17
  • 2022-12-23
  • 2014-11-07
  • 2015-07-08
  • 1970-01-01
  • 1970-01-01
  • 2015-12-10
  • 2011-03-04
  • 1970-01-01
相关资源
最近更新 更多