2010-06-24 4 views
4

Après de nombreuses recherches sur Internet, j'ai implémenté une petite routine assembleur dans mon programme C++ pour obtenir la taille de la mémoire cache L1 du processeur en utilisant cpuid.Erreur dans mon premier programme d'assemblage (GCC Inline Assembly)

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

Il fonctionne parfaitement sur Windows 7 64 bits avec MinGW (GCC, G ++). Ensuite, j'ai essayé ceci sur mon ordinateur Mac en utilisant GCC 4.0 et il doit y avoir une erreur quelque part parce que mon programme montre des chaînes étranges dans les ComboBox et certains signaux ne peuvent pas être connectés (Qt GUI).

Ceci est mon premier programme assembleur, j'espère que quelqu'un peut me donner un indice, merci!

+1

Si vous le parcourez avec un débogueur, que voyez-vous se produire? –

+2

@ user363778: Peut-être que vous devriez accepter une réponse de temps en temps? Voici comment faire: http://privat.rejbrand.se/howtoaccept.html –

Répondre

5

Je pense que CPUID claque réellement EAX, EBX, ECX, EDX, donc c'est probablement juste un problème de trash de registre. Le code suivant semble fonctionne correctement avec gcc 4.0.1 et 4.2.1 sur 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; 
} 

Notez que vous devez compiler avec -fno-pic comme EBX est réservé lorsque PIC est activé. (Soit cela ou vous devez prendre des mesures pour enregistrer et restaurer 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

J'ai finalement résolu le problème. Je suis une erreur de compilation lors de la lecture autour de: "Erreur: PIC registre '% EBX' mis à mal dans« asm" et après quelques recherches sur internet, je modifié mon code:

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; 

}

Merci Paul, L'option du compilateur -fno-pic est aussi une bonne solution. Salutations

+1

comme mentionné ci-dessus soyez prudent avec ce code. Ce n'est pas correct sans les clobbers supplémentaires, et vous pourriez avoir des problèmes avec certains niveaux d'optimisation du compilateur (c'est-à-dire surtout si l'optimisation inter-procédures et l'inlining se produisent). –