我的第一个装配程序出错(GCC内联装配)

时间:2010-06-24 20:43:45

标签: gcc assembly g++ inline-assembly

经过大量的互联网研究,我在我的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),因此必定存在错误。

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

2 个答案:

答案 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也是一个很好的解决方案。 问候