如何在 Windows 上检测 X32? [英] How to detect X32 on Windows?

查看:38
本文介绍了如何在 Windows 上检测 X32?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

X32 允许使用在 x86_64 处理器上运行的 32 位整数、长整数和指针编写程序.在某些用例中,使用 X32 有许多好处.(X32 与 X86 或 X64 不同;有关详细信息,请参阅

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

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

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

  • 如果是这样,我如何确定在 Windows 下何时选择了 X32?
  • 如果不是,那么英特尔为什么专门为 Windows 调用 X32 平台?

解决方案

问题

<块引用>

Microsoft 是否真的支持 X32(相对于 X86 和 X64)?

TL;DR 答案

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

<小时>

长答案—第一部分

X32 没有标题字符串"

无视以下事实:

  • 没有关于此类功能的官方文档,
  • Visual Studio 或 cl.exe/? 中没有选项可以启用/禁用它,并且
  • strings -el clui.dll 没有显示此类选项的迹象,

strings -el "%VCINSTALLDIR%in1033clui.dll" |find "Microsoft (R)" 也没有显示匹配标题字符串的迹象:

4Microsoft (R) C/C++ 优化编译器版本 %s- 对于 Microsoft (R) .NET Framework 版本 %s(Microsoft (R) C/C++ 优化编译器FMicrosoft (R) C/C++ 优化编译器版本 %s 用于 MIPS R 系列)Microsoft (R) MIPS 汇编程序版本 %sCMicrosoft (R) C/C++ 优化编译器版本 %s for Renesas SH<Microsoft (R) C/C++ 优化编译器版本 %s for ARM:Microsoft (R) C/C++ 标准编译器版本 %s for x86<Microsoft (R) C/C++ 优化编译器版本 %s for x86GMicrosoft (R) 32 位 C/C++ 优化编译器版本 %s for PowerPC@Microsoft (R) C/C++ 优化编译器版本 %s for Itanium<Microsoft (R) C/C++ 优化编译器版本 %s for x64>Microsoft (R) C/C++ 优化编译器版本 %s for ARM64Microsoft (R) MIPS 汇编程序

binx86_amd641033clui.dllbinx86_arm1033clui.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__//使用 X32 版本的 myfunc().extern long myfunc_x32 (const char *);long (*myfunc)(const char *) = myfunc_x32;# else/* !__ILP32__ *///使用 AMD64 版本的 myfunc().extern long myfunc_amd64 (const char *);long (*myfunc)(const char *) = myfunc_amd64;# endif/* __ILP32__ *//* !__x86_64__ */#elif 定义了 __i386__//使用 x86 版本的 myfunc().extern long myfunc_x86 (const char *);long (*myfunc)(const char *) = myfunc_x86;/* !__i386__ */#别的//使用 myfunc() 的通用版本,因为没有可用的优化版本.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代码>也被定义了.

<小时>

长答案—第三部分

坏消息"

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

<小时>

长答案—新的希望破灭了

这些不是您要找的宏"

假设可以使用当前存在的宏来检查,但在这种情况下它没有帮助,因为 X32 for Windows 不存在.它与 GLIBC 检查并无不同,但如果 __ILP32__ 被定义,则不是启用 X32,而是在 _M_X64 未定义时启用它.

#ifdef _M_AMD64# ifndef _M_X64# 定义 ABI_STR "X32"# 别的# 定义 ABI_STR "AMD64"# 万一#elif 定义了_M_IX86# 定义 ABI_STR "X86"#别的# 错误不受支持的 CPU/架构#万一

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

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?

解决方案

The question

Does Microsoft actually support X32 (as opposed to X86 and X64)?

TL;DR answer

The answer is "No, it's not supported by Microsoft." The preprocessor macros don't lead to any identification of X32, the command line options and IDE options don't exist, and the strings identifying such a compiler don't exist.


The long answer — Part I

"There are no header strings for X32"

Disregarding the following facts:

  • no official documentation of such a feature exists,
  • no option in Visual Studio or cl.exe /? to enable/disable it exists, and
  • strings -el clui.dll shows no sign of such an option,

strings -el "%VCINSTALLDIR%in1033clui.dll" | find "Microsoft (R)" shows no sign of a matching header string either:

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

The same output is seen in the binx86_amd641033clui.dll and binx86_arm1033clui.dll files, so it's not like that one file simply didn't include it.


The long answer — Part II

"Windows doesn't do data models"

Let's suppose it did. How would you detect it? In the case of GLIBC, __ILP32__ is defined for x32 and x86 while __LP64__ is defined for amd64, denoting the data model used. Additionally, __x86_64__ will be defined for the AMD64 architecture. If __x86_64__ is defined and __ILP32__ is defined, then you're using the X32 ABI, else you're using the AMD64 ABI. For C, that's all that matters. If you're utilizing assembly code, that's where the differentiation between the X32 ABI and the x86 ABI matters, hence checking __x86_64__ to determine that the architecture targeted is 64-bit and checking __ILP32__ to determine whether the 32-bit or 64-bit ABI is in use. For example:

#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__ */

However, there is no macro indicating the data model on Windows. You target one of the following architectures:

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

Theoretically one could use _M_AMD64 and _M_X64 independently to determine whether X32 exists, but if _M_AMD64 is defined, _M_X64 is also defined.


The long answer — Part III

"The bad news"

In the end, after searching to find anything, perhaps even long forgotten material, there is no evidence that Windows has supported or ever will support coding for an X32 ABI like Linux. The preprocessor macros don't help in identifying X32, the command line options and IDE options don't exist, and the strings identifying such a compiler don't exist.


The long answer — A new hope dashed

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

One could hypothetically use the currently existing macros to check, but it's not like it helps in this case because X32 for Windows doesn't exist. It's not unlike the GLIBC check, though instead of enabling X32 if __ILP32__ is defined, you enable it if _M_X64 is not defined.

#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

Of course, if _M_AMD64 is defined, then _M_X64 is defined too, further reinforcing the evidence that there is no X32 for Windows.

这篇关于如何在 Windows 上检测 X32?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆