如何在Windows上检测X32?

jww*_*jww 1 windows abi 32bit-64bit c-preprocessor linux-x32-abi

X32允许用户使用在x86_64处理器上运行的32位整数,长整数和指针来编写程序.在某些使用案例中,使用X32有许多好处.(X32与X86或X64 不同 ; 有关详细信息,请参阅x86,x32和x64体系结构之间的差异).

一些Windows Enterprise Server似乎支持X32,但我无法找到更多信息.这是基于一些英特尔PDF,如基于英特尔®至强®处理器E5-2400系列的智能系统平台:

在此输入图像描述

微软关于预定义宏的文档列出了常见的嫌疑,比如_M_X64_M_AMD64.但它似乎没有讨论X32的架构选项.

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

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

如果是这样,我如何确定何时在Windows下选择X32?

如果没有,那么为什么英特尔专门为Windows推出X32平台呢?

小智 5

这个问题

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

TL; DR回答

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


答案很长 - 第一部分

"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
Run Code Online (Sandbox Code Playgroud)

bin\x86_amd64\1033\clui.dllbin\x86_arm\1033\clui.dll文件中看到相同的输出,所以它不像是一个文件根本不包含它.


答案很长 - 第二部分

"Windows不做数据模型"

让我们假设它做到了.你怎么会发现它?在GLIBC的情况下,__ILP32__为x32和x86 __LP64__定义,而为amd64定义,表示使用的数据模型.此外,__x86_64__还将为AMD64架构定义.如果__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__ */
Run Code Online (Sandbox Code Playgroud)

但是,没有宏指示Windows上的数据模型.您可以定位以下架构之一:

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

从理论上讲,可以使用_M_AMD64_M_X64独立地确定X32是否存在,但是如果_M_AMD64定义了X32 _M_X64也是如此.


答案很长 - 第三部分

"坏消息"

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


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

"这些不是你正在寻找的宏"

可以假设使用当前存在的宏进行检查,但在这种情况下它并不像它有帮助,因为X32 for Windows不存在.它与GLIBC检查没有什么不同,但如果__ILP32__定义了X32而不启用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
Run Code Online (Sandbox Code Playgroud)

当然,如果_M_AMD64定义了,那么_M_X64也定义了,进一步强化了没有X32 for Windows的证据.