質問

I would like to ask on two things about .NET executables:

  1. .NET executable is in PE format. Does it mean that address generated by CIL compiler is from the beginning of the file (address+size_of_headers)? Or are these address used only when executing image in memory?

  2. Is it possible to generate (by CIL compiler) executable with size greater than 4GB? If yes, what does the compiler do if it has to call method from the end of file or branch to byte above the 4GB limit?

It's true I have never seen any C# executable greater than 4GB, I'm just curios.

役に立ちましたか?

解決

I think you're confusing how executing CIL works with how executing native code works.

With CIL, the code that is in the executable file is not actually executed. Usually (with the desktop CLR and without ngen) the CLR reads the CIL and generates actual executable code on the fly (that's why this part of the CLR is called “just in time compiler”).

CIL opcodes like call use tokens to reference methods and other members. In the generated native code, those are translated into the address of the native code for that method.

Opcodes like br contain offsets relative to the next CIL instruction and they can jump only inside the current method. On x86, they are compiled to instructions like jne, which contain offsets relative to the next x86 instruction.

But the metadata for a method is described in the MethodDef table, which contains reference to the IL stream for that method as a 4-byte Relative Virtual Address (and RVAs are used in other parts of the file too). I think this means that the executable file can't actually be more than 4 GB in size.

I attempted to verify this by creating a large executable using Reflection.Emit. But the best I could do on my system with 8 GB of RAM was crating a 1.5 GB big file (which already made the computer unusable due to swapping).

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top