是否可以使用相同字节的机器代码来确定它们是以32位还是64位模式运行,然后执行不同的操作?
即写多语言机器代码.
通常,您可以在构建时使用#ifdef宏检测.或者在C中,您可以编写一个if()以编译时常量作为条件,并让编译器优化它的另一面.
这仅适用于奇怪的情况,例如代码注入,或只是为了查看是否可能.
另请参见:多语言ARM/x86机器代码,用于分支到不同的地址,具体取决于解码字节的架构.
在为Windows编写新代码时,我偶然发现_cpuinfo()了Windows API.因为我主要处理Linux环境(GCC),所以我希望能够访问CPUInfo.
我尝试过以下方法:
#include <iostream>
int main()
{
int a, b;
for (a = 0; a < 5; a++)
{
__asm ( "mov %1, %%eax; " // a into eax
"cpuid;"
"mov %%eax, %0;" // eax into b
:"=r"(b) // output
:"r"(a) // input
:"%eax","%ebx","%ecx","%edx" // clobbered register
);
std::cout << "The code " << a << " gives " << b << std::endl;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这使用组件,但我不想重新发明轮子.有没有其他方法可以在没有汇编的情况下实现CPUInfo?
编译器错误:
lewis@lewis-desktop:~/Desktop/prog$ g++ -Wall CPUInfo.cpp
CPUInfo.cpp: In function ‘int …Run Code Online (Sandbox Code Playgroud) 首先我了解(或者我认为我了解)堆栈未对齐的问题。
但我知道(就像定义一样)将 16 位值推入 32 位宽堆栈可能会导致堆栈未对齐。
但我不明白的是,这是如何发生的......因为PUSH并POP检查段描述符处的 D 标志(因此 1 递增/递减 32 位,0 是 16 位)。
假设D flag=1,应该PUSH AX做32bits减1吗?所以这就像我“错过”堆栈中的 16 位?
我不确定我是否理解这个问题
我需要找到CPU的架构类型.我没有访问/ proc/cpuinfo,因为机器正在运行syslinux.我知道有一种方法可以使用内联ASM,但我相信我的语法不正确,因为我的变量iedx没有正确设置.
我和ASM一起苦苦挣扎,绝不是专家.如果有人有任何提示或能指出我正确的方向,我会非常感激.
static int is64Bit(void) {
int iedx = 0;
asm("mov %eax, 0x80000001");
asm("cpuid");
asm("mov %0, %%eax" : : "a" (iedx));
if ((iedx) && (1 << 29))
{
return 1;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud) 是否可以通过低级代码(C/C++或汇编)检查x86/x86-64 CPU中的CPU架构(64位或32位),而无需从操作系统或某些API收集信息?
可以检查指针的大小,就像这里讨论的那样,但是,根据我的理解,这种方式可以让你知道OS体系结构的编译,因为运行32位操作系统的64位CPU会报告错误的结果.
也许一些cpuid指令或类似可以做到这一点,但我找不到任何完全满足这些要求的东西.如果你认为这是不可能的,我会很高兴有理由证明这一点(这可能是一个不太客观的答案).如果您想知道,这是一个CPU检测软件.
编辑:在装配中确定32/64位体系结构时,OP没有得到解释如何操作的特定答案,只是你应该使用cpuid,并链接到如何在运行时使用GCC检测CPU体系结构类型和内联asm?,这显示了一个很好的答案,但它没有我标记为接受的答案那么完整,因为Remy Lebeau给出了详细的解释,并告诉必须查询哪个特定的cpuid位,而不是仅仅编写一些代码,以及我发现它对我的问题更合适,因为它是在更高级别的范围内解释的(我从未提及gcc,第二篇文章的确如此)