我想问一下有关.NET可执行文件的两件事:
.NET可执行文件采用PE格式。这是否意味着CIL编译器生成的地址是从文件的开头(address+size_of_headers
)?或者这些地址仅在内存中执行图像时使用?
是否可以生成(通过CIL编译器)大小超过4GB的可执行文件?如果是,如果编译器必须从文件末尾调用方法或分支到高于4GB限制的字节,编译器会做什么?
我从未见过任何大于4GB的C#可执行文件,我只是好奇。
答案 0 :(得分:2)
我认为你在处理CIL如何处理本机代码的工作方式时会感到困惑。
使用CIL,实际上不会执行可执行文件中的代码。通常(使用桌面CLR且没有ngen)CLR会读取CIL并动态生成实际的可执行代码(这就是为什么CLR的这部分被称为“及时编译器”)。
像call
这样的CIL操作码使用标记来引用方法和其他成员。在生成的本机代码中,这些代码被转换为该方法的本机代码的地址。
br
等操作码包含相对于下一个CIL指令的偏移量,它们只能在当前方法内跳转。在x86上,它们被编译为jne
之类的指令,它们包含相对于下一个x86指令的偏移量。
但是MethodDef
表中描述了方法的元数据,该表包含对该方法的IL流的引用,为4字节Relative Virtual Address(并且在其他部分使用了RVAs)文件也是)。我认为这意味着可执行文件的大小实际上不能超过4 GB。
我试图通过使用Reflection.Emit创建一个大型可执行文件来验证这一点。但是我在系统上用8 GB RAM做的最好的事情是装了一个1.5 GB的大文件(由于交换已经使计算机无法使用)。