经过大量的互联网研究,我在我的C ++程序中实现了一个小的汇编程序,用cpuid获取CPU的L1缓存大小。
int CPUID_getL1CacheSize() {
int l1CacheSize = -1;
asm ( "mov $5, %%eax\n\t" // EAX=80000005h: L1 Cache and TLB Identifiers
"cpuid\n\t"
"mov %%eax, %0" // eax into l1CacheSize
: "=r"(l1CacheSize) // output
: // no input
: "%eax" // clobbered register
);
return l1CacheSize;
}
在带有MinGW(GCC,G ++)的Windows 7 64位上完美运行。接下来我在Mac计算机上使用GCC 4.0尝试了这个,因为我的程序在ComboBox中显示奇怪的字符串并且某些信号无法连接(Qt GUI),因此必定存在错误。
这是我的第一个汇编程序,希望有人能给我一个提示,谢谢!
答案 0 :(得分:5)
我认为CPUID实际上破坏了EAX,EBX,ECX,EDX,所以它可能只是一个寄存器垃圾问题。以下代码似乎在Mac OS X上使用gcc 4.0.1和4.2.1正常工作:
#include <stdio.h>
int CPUID_getL1CacheSize()
{
int l1CacheSize = -1;
asm ( "mov $5, %%eax\n\t" // EAX=80000005h: L1 Cache and TLB Identifiers
"cpuid\n\t"
"mov %%eax, %0" // eax into l1CacheSize
: "=r"(l1CacheSize) // output
: // no input
: "%eax", "%ebx", "%ecx", "%edx" // clobbered registers
);
return l1CacheSize;
}
int main(void)
{
printf("CPUID_getL1CacheSize = %d\n", CPUID_getL1CacheSize());
return 0;
}
请注意,需要使用-fno-pic
进行编译,因为启用PIC时保留EBX。 (或者您需要采取措施来保存和恢复EBX)。
$ gcc-4.0 -Wall -fno-pic cpuid2.c -o cpuid2
$ ./cpuid2
CPUID_getL1CacheSize = 64
$ gcc-4.2 -Wall -fno-pic cpuid2.c -o cpuid2
$ ./cpuid2
CPUID_getL1CacheSize = 64
$
答案 1 :(得分:0)
我终于解决了这个问题。我在玩游戏时遇到编译器错误:“错误:PIC寄存器'%ebx'在'asm'中被破坏了”并且经过一些互联网研究后我将我的代码修改为:
int CPUID_getL1CacheSize(){
int l1CacheSize = -1;
asm volatile ( "mov $5, %%eax\n\t"
"pushl %%ebx; cpuid; popl %%ebx\n\t"
"mov %%eax, %0"
: "=r"(l1CacheSize)
:
: "%eax"
);
return l1CacheSize;
}
感谢Paul,编译器选项-fno-pic也是一个很好的解决方案。 问候