5

经过大量互联网研究后,我在我的 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 位上完美运行。接下来,我在使用 GCC 4.0 的 Mac 计算机上尝试了此操作,但一定有错误,因为我的程序在 ComboBoxes 中显示奇怪的字符串,并且无法连接某些信号(Qt GUI)。

这是我的第一个汇编程序,希望有人能给我提示,谢谢!

4

2 回答 2

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
$ 
于 2010-06-24T21:37:36.123 回答
0

我终于解决了这个问题。我在玩耍时遇到编译器错误:“错误:PIC register '%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 也是一个不错的解决方案。问候

于 2010-06-24T22:04:57.580 回答