После большого интернет-исследования я реализовал маленькую ассемблерную стандартную программу в своей программе C++ для получения размера кэша ЦП L1 с помощью cpuid.
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;
}
Это работает отлично над Windows 7 64 бита с MinGW (GCC, G ++). Затем я попробовал это на своем Mac использующий компьютеры GCC 4.0 и должна быть ошибка где-нибудь, потому что моя программа показывает странные строки в ComboBoxes, и некоторые сигналы не могут быть соединены (QT GUI).
Это - моя первая ассемблерная программа, я надеюсь, что кто-то может дать мне подсказку, Спасибо!
Я думаю, что CPUID на самом деле затирает EAX, EBX, ECX, EDX, так что это, вероятно, просто проблема с удалением регистров. Следующий код работает нормально с gcc 4.0.1 и 4.2.1 в Mac OS X:
#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
, поскольку EBX зарезервирован, когда PIC включен. (Либо так, либо вам нужно предпринять шаги для сохранения и восстановления 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
$
Я наконец решил проблему. Во время игры у меня возникла ошибка компилятора: «error: PIC register '% ebx' clobbered in '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;
}
Спасибо, Пол, опция компилятора -fno-pic тоже хорошее решение. Приветствую