Ошибка в моей первой программе сборки (Встроенный ассемблерный код GCC)

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

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

5
задан starblue 25 June 2010 в 22:00
поделиться

2 ответа

Я думаю, что 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
$ 
5
ответ дан 14 December 2019 в 18:58
поделиться

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

0
ответ дан 14 December 2019 в 18:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: