X32允许用户使用在x86_64处理器上运行的32位整数,长整数和指针来编写程序。在某些使用案例中,使用X32有许多好处。 (X32与X86或X64不同;有关详细信息,请参阅Difference between x86, x32, and x64 architectures)。
一些Windows Enterprise Server似乎支持X32,但我无法找到更多信息。这是基于一些英特尔PDF,如Intel® Xeon® Processor E5-2400 Series-based Platforms for Intelligent Systems:
微软关于Predefined Macros的文档列出了常见的嫌疑人,如_M_X64
和_M_AMD64
。但它似乎没有讨论X32的架构选项。
如果Microsoft支持X32,那么我怀疑它将是一个类似于大地址空间感知或终端服务感知的选项。
Microsoft实际上是否支持X32(而不是X86和X64)?
Microsoft实际上是否支持X32(而不是X86和X64)?
答案是“不,微软不支持它。”预处理器宏不会导致任何X32标识,命令行选项和IDE选项不存在,并且标识此类编译器的字符串不存在。
无视以下事实:
cl.exe /?
中没有选项来启用/禁用它,并且strings -el clui.dll
没有显示这种选择的迹象,strings -el "%VCINSTALLDIR%\bin\1033\clui.dll" | find "Microsoft (R)"
也没有显示匹配标题字符串的迹象:
4Microsoft (R) C/C++ Optimizing Compiler Version %s
-for Microsoft (R) .NET Framework version %s
(Microsoft (R) C/C++ Optimizing Compiler
FMicrosoft (R) C/C++ Optimizing Compiler Version %s for MIPS R-Series
)Microsoft (R) MIPS Assembler Version %s
CMicrosoft (R) C/C++ Optimizing Compiler Version %s for Renesas SH
<Microsoft (R) C/C++ Optimizing Compiler Version %s for ARM
:Microsoft (R) C/C++ Standard Compiler Version %s for x86
<Microsoft (R) C/C++ Optimizing Compiler Version %s for x86
GMicrosoft (R) 32-bit C/C++ Optimizing Compiler Version %s for PowerPC
@Microsoft (R) C/C++ Optimizing Compiler Version %s for Itanium
<Microsoft (R) C/C++ Optimizing Compiler Version %s for x64
>Microsoft (R) C/C++ Optimizing Compiler Version %s for ARM64
Microsoft (R) MIPS Assembler
在bin\x86_amd64\1033\clui.dll
和bin\x86_arm\1033\clui.dll
文件中可以看到相同的输出,因此它不像是一个文件根本不包含它。
让我们假设它做到了。你怎么会发现它?在GLIBC的情况下,__ILP32__
定义为x32和x86,而__LP64__
定义为amd64,表示the data model used。此外,将为AMD64架构定义__x86_64__
。如果定义了__x86_64__
并且定义了__ILP32__
,那么你正在使用X32 ABI,否则你正在使用AMD64 ABI。对于C来说,重要的是这一切。如果您正在使用汇编代码,那么X32 ABI和x86 ABI之间的区别很重要,因此检查__x86_64__
以确定目标架构是64位并检查__ILP32__
以确定32位还是64位ABI正在使用中。例如:
#ifdef __x86_64__
# ifdef __ILP32__
// Use X32 version of myfunc().
extern long myfunc_x32 (const char *);
long (*myfunc)(const char *) = myfunc_x32;
# else /* !__ILP32__ */
// Use AMD64 version of myfunc().
extern long myfunc_amd64 (const char *);
long (*myfunc)(const char *) = myfunc_amd64;
# endif /* __ILP32__ */
/* !__x86_64__ */
#elif defined __i386__
// Use x86 version of myfunc().
extern long myfunc_x86 (const char *);
long (*myfunc)(const char *) = myfunc_x86;
/* !__i386__ */
#else
// Use generic version of myfunc() since no optimized versions are available.
long myfunc(const char *);
#endif /* __x86_64__ */
但是,没有宏指示Windows上的数据模型。您可以定位以下架构之一:
_M_IX86
)_M_AMD64
/ _M_X64
)_M_ARM
)从理论上讲,人们可以独立地使用_M_AMD64
和_M_X64
来确定是否存在X32,但如果定义了_M_AMD64
,则还定义了_M_X64
。
最后,在寻找任何东西,甚至可能是长期遗忘的材料之后,没有证据表明Windows已经支持或者将支持编码像Linux这样的X32 ABI。预处理器宏无法识别X32,命令行选项和IDE选项不存在,并且标识此类编译器的字符串不存在。
可以假设使用当前存在的宏进行检查,但在这种情况下它并不像它有帮助,因为X32 for Windows不存在。它与GLIBC检查没有什么不同,但如果定义了__ILP32__
,则不启用X32,如果未定义_M_X64
,则启用它。
#ifdef _M_AMD64
# ifndef _M_X64
# define ABI_STR "X32"
# else
# define ABI_STR "AMD64"
# endif
#elif defined _M_IX86
# define ABI_STR "X86"
#else
# error unsupported CPU/architecture
#endif
当然,如果定义了_M_AMD64
,那么也定义了_M_X64
,进一步强化了Windows没有X32的证据。
Microsoft实际上是否支持X32(而不是X86和X64)?
没有。
Windows没有x32 ABI。但是它具有仅在低2GB的地址空间中为您提供内存的功能。只需禁用/LARGEADDRESSAWARE
标志(默认情况下它已启用64位二进制文件)然后您可以在64位应用程序中使用32位指针
这些二进制文件中的用户空间指针将顶部位置为零,因此它基本上类似于Linux上的x32 ABI。 Windows中的long
一直是32位类型,因此它也与x32 ABI中的相同,其中long
和指针是32位宽
默认情况下,64位基于Microsoft Windows的应用程序具有几TB的用户模式地址空间。有关精确值,请参阅Windows和Windows Server版本的内存限制。但是,应用程序可以指定系统应为应用程序分配低于2千兆字节的所有内存。如果满足以下条件,则此功能对64位应用程序有益:
- 2 GB的地址空间就足够了。
- 代码有许多指针截断警告。
- 指针和整数是自由混合的。
- 该代码具有使用32位数据类型的多态性。
所有指针仍然是64位指针,但系统确保每个内存分配都低于2 GB限制,因此如果应用程序截断指针,则不会丢失重要数据。指针可以截断为32位值,然后通过符号扩展或零扩展扩展为64位值。
但现在甚至在Linux上kernel developers are discussing to drop x32 Support
对于迟到的回答(以及对大卫的不公正)感到抱歉。
我在ml64.exe
上阅读MASM for x64 (ml64.exe),我在汇编程序中遇到了32位地址模式。它提供X32地址大小覆盖。
因此,Windows工具确实提供了与X32相关的支持。它还解释了英特尔如何生产X32二进制文件和驱动程序。我只是猜测,但我怀疑英特尔可能正在使用自定义分配器或VirtualAlloc
来确保指针地址在一定范围内。
Windows操作系统似乎没有自定义构建的内核,比如Debian 8,它提供了操作系统的基础。也就是说,它由开发人员来确保整数,长整数和指针也在32位范围内。
关于给定进程禁用/ LARGEADDRESSAWARE的phuclv答案的小脚注:在某些情况下,当数据结构有利,并且需要采取必要步骤以在64位模式下实际使用32位指针时,性能增益太大Windows,就像在Linux上一样,尽管不是那么大。见:Benchmark of 32-bit pointers in 64-bit code on Windows