如何在Windows上检测X32?

问题描述 投票:1回答:5

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

Intel® Xeon® Processor E5-2400 Series-based Platforms for Intelligent Systems OS support

微软关于Predefined Macros的文档列出了常见的嫌疑人,如_M_X64_M_AMD64。但它似乎没有讨论X32的架构选项。

如果Microsoft支持X32,那么我怀疑它将是一个类似于大地址空间感知或终端服务感知的选项。

Microsoft实际上是否支持X32(而不是X86和X64)?

  • 如果是这样,我如何确定何时在Windows下选择X32?
  • 如果没有,那么为什么英特尔专门为Windows推出X32平台呢?
windows c-preprocessor 32bit-64bit abi linux-x32-abi
5个回答
5
投票

这个问题

Microsoft实际上是否支持X32(而不是X86和X64)?

TL; DR回答

答案是“不,微软不支持它。”预处理器宏不会导致任何X32标识,命令行选项和IDE选项不存在,并且标识此类编译器的字符串不存在。


答案很长 - 第一部分

"There are no header strings for X32"

无视以下事实:

  • 没有关于此类功能的官方文档,
  • 在Visual Studio或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.dllbin\x86_arm\1033\clui.dll文件中可以看到相同的输出,因此它不像是一个文件根本不包含它。


答案很长 - 第二部分

"Windows doesn't do data models"

让我们假设它做到了。你怎么会发现它?在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上的数据模型。您可以定位以下架构之一:

  • 32位x86(_M_IX86
  • 64位AMD64(_M_AMD64 / _M_X64
  • (32位?)ARM(_M_ARM

从理论上讲,人们可以独立地使用_M_AMD64_M_X64来确定是否存在X32,但如果定义了_M_AMD64,则还定义了_M_X64


答案很长 - 第三部分

"The bad news"

最后,在寻找任何东西,甚至可能是长期遗忘的材料之后,没有证据表明Windows已经支持或者将支持编码像Linux这样的X32 ABI。预处理器宏无法识别X32,命令行选项和IDE选项不存在,并且标识此类编译器的字符串不存在。


答案很长 - 一个新的希望破灭了

"These aren't the macros you're looking for"

可以假设使用当前存在的宏进行检查,但在这种情况下它并不像它有帮助,因为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的证据。


1
投票

Microsoft实际上是否支持X32(而不是X86和X64)?

没有。


1
投票

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位值。

Virtual Address Space

但现在甚至在Linux上kernel developers are discussing to drop x32 Support


0
投票

对于迟到的回答(以及对大卫的不公正)感到抱歉。

我在ml64.exe上阅读MASM for x64 (ml64.exe),我在汇编程序中遇到了32位地址模式。它提供X32地址大小覆盖。

因此,Windows工具确实提供了与X32相关的支持。它还解释了英特尔如何生产X32二进制文件和驱动程序。我只是猜测,但我怀疑英特尔可能正在使用自定义分配器或VirtualAlloc来确保指针地址在一定范围内。

Windows操作系统似乎没有自定义构建的内核,比如Debian 8,它提供了操作系统的基础。也就是说,它由开发人员来确保整数,长整数和指针也在32位范围内。


0
投票

关于给定进程禁用/ LARGEADDRESSAWARE的phuclv答案的小脚注:在某些情况下,当数据结构有利,并且需要采取必要步骤以在64位模式下实际使用32位指针时,性能增益太大Windows,就像在Linux上一样,尽管不是那么大。见:Benchmark of 32-bit pointers in 64-bit code on Windows

© www.soinside.com 2019 - 2024. All rights reserved.