Monday, September 2, 2013

Prefer 32-Bit with Any CPU Platform Target - Visual Studio 2012 Enhancements

Visual Studio allows us to compile our code targeting x86 or x64 platforms by clearly specifying platform targets. We can also compile against Any CPU option. This allows the run-time to JIT the assembly in 32 or 64-bit code based on the type of process it is loaded in. Compiling an application against 32-bit would not stop it from running on a 64-bit windows platform, it would just use WOW64. We have discussed about WOW64 long back here.

In order to target an application to 32 or 64-bit, we can just specify the platform target for the start-up project in its property page. I am sure the readers, of this blog, have seen this page a lot of times. Here you seen the Any CPU target. In Visual Studio 2010 the Build tab in project's property page looks as follows:



With other various updates, Visual Studio 2012 has improved on Any CPU a little. Now selecting Any CPU allows us to further qualify our selection. Please notice Prefer-32 bit option here.



Let's see how the IL looks like. You can see that the assembly is compiled differently.



The new framework should be able to handle this option. This is why you see the option greyed out when we select any such framework including .net framework 4.0. It should be available for .net framework 4.5.



This option is only for executable type of projects(*.EXE). For all other project types as well, you should find this option greyed out.

Compiling with 32-bit Preferred
Setting the option in Visual studio causes the new compiler switch to be used for the project. The project is compiled using C# compiler (csc.exe) with switch anycpu32bitpreferred You can find further details about the compiler switch here on msdn.

CorFlags 32-bit
As we know we can set / reset 32-bit flag using CorFlags tool available with Visual Studio. Well the tool has also been updated to support this extra details for such assemblies. Now there are two flags instead. They are 32BITREQ and 32BITPREF.



We can verify the setting of flag by opening an assembly compiled with this option selected. You can see that 32BITPREF flag has been set.



Effects of Setting 32BITPREF
Now we have see how to set this flag and how it would be reflected in the generated assembly. We still haven't discussed what it actually does. Or what it tells to the host framework running the application.

The difference in setting the switch or avoiding Any CPU would make all the difference when the executable is run on a 64-bit operating system. For an application compile without the switch would run it as a 64-bit process. Setting the option would still run it as a 32-bit process even on a 64-bit operating systems. As we know, we can identify a 32-bit process in Task Manager if we find a *32 with its name in Task Manager. We should continue to see them as 32-bit process in Task Manager. As we discussed before, this is exactly how our application should run if we are compiling it with x86 platform target.



The other difference is when the executable is run on ARM Windows system. The ones compiled using Any CPU wouldn't run on an ARM machine (Advanced RISC Machine). With 32-bit preferred, they run as a 32-bit process.

2 comments:

Gabriel Paiz said...

What window is that manifest window in Visual Studio?

Muhammad Shujaat Siddiqi said...

Hi Gabriel, This is ILDASM, a separate Visual Studio tool. You can find it in the installation folder.