X32 allows one to write programs using 32-bit integers, longs and pointers that run on x86_64 processors. Using X32 has a number of benefits under certain use cases. (X32 is different than X86 or X64; see Difference between x86, x32, and x64 architectures for more details).
It appears some Windows Enterprise Server supports X32, but I'm having trouble finding more information on it. That's based on some Intel PDFs, like Intel® Xeon® Processor E5-2400 Series-based Platforms for Intelligent Systems:
Microsoft's documentation on Predefined Macros lists the usual suspect, like _M_X64
and _M_AMD64
. But it does not appear to discuss an architecture option for X32.
If Microsoft supports X32, then I suspect it is going to be an option similar to large address space aware or terminal service aware.
Does Microsoft actually support X32 (as opposed to X86 and X64)?
- If so, how can I determine when X32 is being selected under Windows?
- If not, then why does Intel specifically call out the X32 platform for Windows?
Windows doesn't have an x32 ABI. However it has a feature that gives you memory only in the low 2GB of address space. Just disable the
/LARGEADDRESSAWARE
flag (by default it's enabled for 64-bit binaries) and then you can use 32-bit pointers inside your 64-bit applicationUser space pointers in those binaries will have the top bits zeroed, so it's essentially just similar to x32 ABI on Linux.
long
in Windows has always been a 32-bit type, thus it's also the same as in x32 ABI wherelong
and pointers are 32-bit wideBut nowadays even on Linux kernel developers are discussing to drop x32 Support
Detecting whether
/LARGEADDRESSAWARE
is enabled or not is a little bit trickier. Since it's a link-time option, you can't check it during compile-time with any macros. However you can work around that by adding a new config (e.g. x32) to your VS project and in that configAdd a macro (e.g.
_WIN_X32_ABI
) so that you can check the config at compile-timeAdd a post-build event which runs the following commands
Alternatively set the option programmatically from a VS extension using
VCLinkerTool.LargeAddressAware
property. Now just build with this config and you'll get an "x32 ABI" executableTo check the flag of another process or executable file just read the
IMAGE_FILE_LARGE_ADDRESS_AWARE
flag inLOADED_IMAGE::Characteristics
. Determining the flag for the current process is probably trickier so it's better to just use the macro created above to do it at compile timeIntel compiler also has an option to use the ILP32 model on 64-bit Windows/Linux/macOS called
-auto-ilp32
and/Qauto-ilp32
:There's also
-auto-p32
to shrink only pointers and not 64-bit longHowever I couldn't find a way to check that behavior, as well as how to determine whether pointers have been shrunk to 32-bit or not. I've tried
-auto-ilp32 -xCORE-AVX512 -O2 -ipo
on Godbolt but it seem doesn't affect the result. If any one knows how to output an executable with 32-bit pointers please tell me