2010-06-24 4 views
4

많은 인터넷 조사를 마친 후 cpuid를 사용하여 CPU의 L1 캐시 크기를 얻으려면 C++ 프로그램에서 작은 어셈블러 루틴을 구현했습니다.첫 번째 어셈블리 프로그램 (GCC 인라인 어셈블리)에서 오류가 발생했습니다.

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 컴퓨터에서이 작업을 시도했는데 내 프로그램이 ComboBox에서 이상한 문자열을 표시하고 일부 신호를 연결할 수 없기 때문에 오류가 발생했습니다 (Qt GUI).

이것은 내 첫 번째 어셈블러 프로그램입니다. 누군가가 나에게 힌트를 줄 수 있기를 바랍니다. 감사합니다.

+1

디버거를 사용하여 단계별로 진행하면 어떻게됩니까? –

+2

@ user363778 : 어쩌면 당신은 매 순간마다 대답을 받아 들여야합니까? 이렇게하는 방법입니다 : http://privat.rejbrand.se/howtoaccept.html –

답변

5

나는 CPUID가 실제로 EAX, EBX, ECX, EDX를 clobbers한다고 생각하기 때문에 아마 문제를 그냥 쓰레기로 처리 할 것입니다. 다음 코드는 맥 OS X에서 GCC 4.0.1과 4.2.1에 확인 작업이 나타납니다 : 당신이 PIC를 사용할 때 EBX가 예약되어 -fno-pic로 컴파일해야

#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; 
} 

참고. (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 
$ 
0

마지막으로 문제가 해결되었습니다.

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; 
: 나는 내 코드를 수정 일부 인터넷 연구 후 : "오류 : PIC는 'ASM'에서 사방 '%의 EBX을'등록 '주위를 재생하는 동안 나는 컴파일러 오류가 발생했습니다

}

고마워 폴, 컴파일러 옵션 -fno-pic도 좋은 해결책입니다. 인사말

+1

위에서 언급 한 바와 같이이 코드는주의해야합니다. 추가적인 clobbers가 없으면 정확하지 않으며 컴파일러 최적화 수준에 문제가 발생할 수 있습니다 (특히 프로 시저 간 최적화 및 인라인이 발생하는 경우). –