在汇编中确定32位/64位架构

6
我在阅读这个问题时想知道是否接受的答案也可以确定体系结构。例如,在汇编语言中,我可以将WORD推入堆栈,然后检查SP。比较新的SP和旧的SP:

差值为4表示32位
差值为8表示64位

我的想法正确吗?


2
我曾经认为32位和64位汇编指令是不同的。至少在x86与x86-64中是这样的。 - Powerlord
3
如果您只是想检测64位支持,您可以使用CPUID指令。我不知道具体情况,请您自行判断。 - Andreas Rejbrand
2
通常在编译时就知道目标是64位还是32位。这个技巧很少有用到的情况。而且,我猜测有一种直接检查相关标志的方法,而不必像这样做一些技巧性的操作。 - Dietrich Epp
@OMG: 对于push和pop指令,它们的操作码是相同的。例如,在x86架构中,无论在哪种模式下,0xFF都表示push操作。处理器会根据执行模式来确定正确的堆栈大小。 - Jeff B
你需要指定你所讨论的CPU/架构 - 我猜你只对x86/x86-64感兴趣,但你没有适当地标记,所以谁知道呢? - Paul R
1
有关检测运行模式的机器码,请参见此函数,该函数返回16、32或64:确定您的语言版本。或者仅查看32位与64位,请参见x86-32 / x86-64多语言机器码片段,可在运行时检测64位模式? - Peter Cordes
2个回答

6
不可以,因为你的堆栈大小取决于你运行的模式(实模式、保护模式、长/64位模式、vm86、smm等),而不是基于体系结构。例如,如果您的汇编代码在保护模式下运行,则您的堆栈将是32位(如果操作数为16位,则为16位),即使您的处理器是x86-64也是如此。
就像评论中的某个人提到的那样,CPUID是唯一可靠的方法来确定您的体系结构。

0

如果要检测机器码运行模式,请参考这个代码高尔夫 x86 机器码函数,它返回16、32或64:Determine your language's version。相同的机器码字节在不同的解码模式下会产生不同的结果。

或者只需要检测32位与64位,可以参考x86-32 / x86-64 polyglot machine-code fragment that detects 64bit mode at run-time?

在大多数情况下,您不需要检测当前模式,因为您知道您的代码是编译/汇编的。例如({{link3:在NASM中,%ifidn __BITS__ 32}),或者检查%ifidn __OUTPUT_FORMAT__, elf32,这也适用于YASM。


使用CPUID可以检测CPU的能力,而不受当前模式的影响。如何在运行时使用GCC和内联汇编检测CPU架构类型?(或者使用cpuid.h: 如何在Linux中调用“cpuid”?

这仍然不能告诉您正在运行的操作系统是否支持64位可执行文件;如果您想知道,您应该检查您是否在64位操作系统下运行。CPUID无法帮助您解决这个问题:32位程序查询操作系统的机制当然是特定于操作系统的。

在几乎所有情况下,“您的CPU架构”都不是正确的问题,除非您正在编写自己的内核或编写CPU信息程序。知道它并不能帮助您的程序决定要做什么。

32位x86 CPU已经很多年没有生产了,越来越稀少。但是32位操作系统仍在64位CPU上使用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接