Ever wondered why Visual Studio IDE provides 3 options for compilation - x86
, x64
and Any CPU
?
While most are aware of these options, many still lack clarity on the significance of these options (including me earlier in my career). So, as part of this article, I hope to clear some of these doubts.
Windows OS has evolved over the years, right from the time it started out as a 16-bit OS, then transitioned to 32-bit (x86
) and more recently to 64-bit (x64
).
Why Would You Use a 64-bit OS over 32-bit?
To understand this, let's understand the capabilities of both 32-bit and 64-bit CPUs.
Understanding the Behaviour of 32-bit, 64-bit and Any CPU compiled PE Files
-
On a 32-bit machine:
- Any CPU: Runs as a 32-bit process, can load Any CPU and
x86
assemblies, will get BadImageFormatException
if it tries to load an x64
assembly. - Any CPU-32-bit preferred (default): Same as Any CPU.
- x86: Same as Any CPU.
- x64:
BadImageFormatException
always.
-
On a 64-bit machine:
- Any CPU: Runs as a 64-bit process, can load Any CPU and
x64
assemblies, will get BadImageFormatException
if it tries to load an x86
assembly. - Any CPU-32-bit preferred (default): Runs as a 32-bit process, can load Any CPU and
x86
assemblies, will get BadImageFormatException
if it tries to load an x64
assembly. - x86: Runs as a 32-bit process, can load Any CPU and
x86
assemblies, will get BadImageFormatException
if it tries to load an x64
assembly. - x64: Same as Any CPU.
Any CPU-32-bit Preferred
This is a new option introduced starting with .NET 4.5 and Visual Studio 11. It is a new subtype of Any CPU and is also the default compilation option in the IDE.
You can check this in the project properties as shown in the screenshot below …
How 32-bit PEs Work on 64-bit Architectures?
- Generally, only 32-bit PEs can be loaded into a 32-bit process, and only 64-bit PEs can be loaded into a 64 bit process.
- When a 32-bit PE is launched on a 64-bit OS, it runs in the “WOW” (Windows-32 on Windows-64) to present an illusion of a 32-bit operating system to the process.
Why Was the Any CPU Compilation Option Introduced?
- Now before 64-bit Windows OS was introduced, there was just the 32-bit PEs (of course, we are not considering 16-bit OS in this discussion) and hence during compilation, these PEs were marked as 32-bit and there was no ambiguity.
- With the introduction of 64-bit Windows OS, a decision had to be made – should the binaries be marked as 32-bit or 64-bit by default?
- Technically speaking, managed binaries have no hard CPU dependency – they could be either 32 or 64 bit.
- However, there was a way required to reuse .NET libraries from both 32-bit and 64-bit processes. For this, the OS loader support was extended to support architecture-neutral PE files (Any CPU).
- In case of Any CPU PEs, the OS loader decides how to initialize the process. On 64-bit OSs, they are run as 64-bit processes, and on 32-bit OSs, they are run as 32-bit processes.
Hope this post helped clarify a few things!!
I’ll also touch upon how to identify the architecture affinity of a PE in a future post.
Abbreviations
- PE: Process Executables (EXEs and DLLs)
References
The post Dealing with 32-bit, 64-bit and Any CPU compilation options in .NET appeared first on Sundeep Kamath's blog.