dotNet Assembly More Basic Understanding[anycpu 32bit/64bit assembly/executable/clr]
1. AnyCPU
Firstly, there are 32bit/64bit CLR. For executables, it's up to the CPU bit to decide whether it will load as a 32/64bit process with corresponding CLR; for assembly, it's up to the process it's to be loaded into NOT the CPU or OS bit.
/platform (Specify Output Platform) (C# Compiler Options)
Remarks
-
x86 compiles your assembly to be run by the 32-bit, x86-compatible common language runtime.
-
Itanium compiles your assembly to be run by the 64-bit common language runtime on a computer with an Itanium processor.
-
x64 compiles your assembly to be run by the 64-bit common language runtime on a computer that supports the AMD64 or EM64T instruction set.
- anycpu (default) compiles your assembly to run on any platform.
On a 64-bit Windows operating system:
-
Assemblies compiled with /platform:x86 will execute on the 32 bit CLR running under WOW64.
-
Executables compiled with the /platform:anycpu will execute on the 64 bit CLR.
- DLLs compiled with the /platform:anycpu will execute on the same CLR as the process into which it is being loaded.
A greate example:
Let's assume we have the following three dlls:
anycpu.dll -- compiled "any cpu"
x86.dll -- compiled "x86"
x64.dll -- compiled "x64"
And the following three exes:
anycpu.exe -- compiled "any cpu"
x86.exe -- compiled "x86"
x64.exe -- compiled "x64"
What happens if you try to use these exes and dlls together? We have to consider two possible scenarios, running on a 32-bit machine and running on a 64-bit machine...
On a 32-bit x86 machine:
anycpu.exe -- runs as a 32-bit process, can load anycpu.dll and x86.dll, will get BadImageFormatException if it tries to load x64.dll
x86.exe -- runs as a 32-bit process, can load anycpu.dll and x86.dll, will get BadImageFormatException if it tries to load x64.dll
x64.exe -- will get BadImageFormatException when it tries to run
On a 64-bit x64 machine:
anycpu.exe -- runs as a 64-bit process, can load anycpu.dll and x64.dll, will get BadImageFormatException if it tries to load x86.dll
x86.exe -- runs as a 32-bit process, can load anycpu.dll and x86.dll, will get BadImageFormatException if it tries to load x64.dll
x64.exe -- runs as a 64-bit process, can load anycpu.dll and x64.dll, will get BadImageFormatException if it tries to load x86.dll
2. dotnet assembly x32bit / x64bit
a dotnet assembly can be compiler targeting anycpu, x32 and x64. Strictly, if it contains only managed code without native code, then it contains only IL. It's really platform agnostic. But in order to let JIT decide the final platform for compiling, there is a header section in dotnet assembly to tell platform info but doesn't contain specific platform code at all:
Corflags.exe is a tool that is shipped as a part of the .NET Framework SDK. It is a powerful tool which allows users to view and configure the corflags section of a PE image. All the data related to platforms is available in this part of the PE image.
A look at an example of a PE header seen from this tool for a 32-bit assembly is below
Version : v2.0.50727
CLR Header : 2.5
PE : PE32
CorFlags : 11
ILONLY : 1
32BIT : 1
Signed : 1
Here is what each component of the header means
Version: Contains the version of .NET Redist with which the binary is built.
CLR Header: 2.0 indicates a .Net 1.0 or .Net 1.1 (Everett) image while 2.5 indicates a .Net 2.0 (Whidbey) image.
CorFlags: This is computed by OR’g specific flags to indicate whether the image is ILONLY, its bitness etc. and is used by the loader.
ILONLY: Managed images are allowed to contain native code. To be “anycpu” an image shall only contain IL.
32BIT: Even if you have an image that only contains IL it still might have platform dependencies, the 32BIT flag is used to distinguish “x86” images from “anycpu” images. 64-bit images are distinguished by the fact that they have a PE type of PE32+.
The most interesting aspect is the PE and the 32BIT flag of the header. These combine to specify the assembly types. Here is how they would look like for:
· anycpu: PE = PE32 and 32BIT = 0
· x86: PE = PE32 and 32BIT = 1
· 64-bit: PE = PE32+ and 32BIT = 0
References:
1. http://blogs.msdn.com/b/rmbyers/archive/2009/06/08/anycpu-exes-are-usually-more-trouble-then-they-re-worth.aspx
2. http://blogs.msdn.com/b/gauravseth/archive/2006/03/07/545104.aspx
3. http://efreedom.com/Question/1-3300877/Best-Way-Support-Multiple-Architectures-Mixed-Managed-Unmanaged-Environment
4. http://blogs.msdn.com/b/joshwil/archive/2005/04/08/406567.aspx
5. http://blogs.msdn.com/b/dsvc/archive/2008/06/28/x86-x64-ia64-any-cpu.aspx