Ошибка в моей первой программе сборки (GCC Inline Assembly) - PullRequest
5 голосов
/ 25 июня 2010

После долгих интернет-исследований я реализовал небольшую программу на ассемблере в своей программе на 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;
}

Он отлично работает на 64-битной Windows 7 с MinGW (GCC)., G ++).Затем я попробовал это на своем компьютере Mac, используя GCC 4.0, и где-то должна быть ошибка, потому что моя программа показывает странные строки в комбинированных списках, и некоторые сигналы не могут быть подключены (Qt GUI).

Это моя первая программа на ассемблереНадеюсь, кто-нибудь подскажет, Спасибо!

Ответы [ 2 ]

5 голосов
/ 25 июня 2010

Я думаю, что 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
$ 
0 голосов
/ 25 июня 2010

Я наконец решил проблему.Я получил ошибку компилятора во время игры: «ошибка: регистр 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;

}

Спасибо, Пол, опция компилятора -fno-pic также является хорошим решением.Привет

...