IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Assembleur Discussion :

Déterminer le CPUID [FAQ]


Sujet :

Assembleur

  1. #1
    Membre confirmé
    Inscrit en
    Mai 2002
    Messages
    117
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 117
    Par défaut Déterminer le CPUID
    Bonjour,

    j'ai un bout de code assembleur écrit depuis C++ mais peu importe. Je l'ai récupéré d'un forum, il permet de récupérer le numéro d'un processeur intel, ou plutot de dire si oui ou non il y a ID. Je voudrais simplement récupérer la valeur de cet ID, et mes connaissances en assembleur sont limité et de plus en plus floues ..... J'ai tenté une syntaxe m:ais il y a peu de chance que ce soit cela, merci de m'aider.
    SerialNumber est une variable entière 16bits, IDProc doit être de quel type ? (en rouge, la solution mais je ne dois pas avoir bon pour la syntaxe, référence, adresse, valeur, &, #, je suis incapable de trouver seul)


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
      __asm 
      { 
       //check if cpuid is supported 
       pushfd 
       pop eax 
       mov ecx,eax //eax=ecx=eflags 
       xor eax,0x200000 
       push eax 
       popfd 
       pushfd 
       pop eax 
       xor eax,ecx//can we toggle bit 21 
       jz _nocpuid 
       push ecx 
       popfd 
     
       mov eax,0h 
       _emit 0x0f 
       _emit 0xa2 //CPUID 
     
       mov eax,0x756e6547 
       cmp ebx,eax 
       jnz _notintel 
       mov eax,0x49656e69 
       cmp edx,eax 
       jnz _notintel 
       mov eax,0x6c65746e 
       cmp ecx,eax 
       jnz _notintel 
     
       mov eax,1h 
       _emit 0x0f 
       _emit 0xa2 //CPUID 
     
       and edx,0x40000 //test bit 18 serial number enabled/supported 
       jz _nonum 
     
       mov SerialNumber,1 
    [color=red]   mov IDProc, &0xa2[/color]
       jmp _exithere 
     
    _nocpuid: 
    _notintel: 
    _nonum: 
       mov SerialNumber,0 
    _exithere: 
    }

    Désolé pour la simplicité de la question, mais ma faible expérience en asm était sur des microcontroleurs, et il y a trop longtemps ......

    Merci d'avance !!

  2. #2
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Août 2002
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 8
    Par défaut
    Bon, je te trouves pas très clair dans ta question.
    alors je vait te mettre dans le bain:

    d'abord, il faut savoir si ton processeur supporte cpuid.
    pour cela:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    BOOL cpuid_sup(void)
    {
    	BOOL sup;
    	asm (
    		"pushfl ;"
    		"popl %%eax ;"
    		"movl %%eax, %%ebx ;"
    		"xorl $0x200000, %%eax ;"
    		"pushl %%eax ;"
    		"popfl ;"
    		"pushfl ;"
    		"popl %%eax ;"
    		"xorl %%ebx, %%eax ;"
    		"jz false ;"
    		"movl $1, %%eax ;"
    		"jmp end ;"
    	"false: ;"
    		"xorl %%eax, %%eax ;"
    		"end: ;"
    		: "=a" (sup)
    		:
    		: "%ebx");
    	return sup;
    }
    Voilà, ca te renvoie TRUE si c'est oui.
    (Se compile avec gcc)
    Si ca, ca te renvoie FALSE, il y a des chances que ce soit un 386. Alors, il faut s'en assurer:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    BOOL is_386(void)
    {
     
    	BOOL ret;
     
    	// 8086/8088, if it was, we can't be here cause we are in pmode :p
    	// 80286, can't switch back to real mode so, we can't be here cause, the BL
    	asm(
    		"pushfl ;"			// Get EFlags
    		"popl %%eax ;"			// in eax
     
    		"movl %%eax, %%ebx ;"		// Save for l8rs
    		"xorl $0x40000, %%eax ;"	// Complete AC bit
     
    		"pushl %%eax ;"			// Re-put
    		"popfl ;"			// in EFlags
     
    		"pushfl ;"			// then, get
    		"popl %%eax ;"			// EFlags in eax for comparing
    		"xorl %%ebx, %%eax ;"		// so, we xor and ...
    		"jz .386 ;"			// if 0, it's a 386
    						// We won !  :p
     
    						// So, we get here if it's a 486 that
    						// doesn't support the cpuid
    						// intruction. We have to restore
    						// the bit AC
     
    		"pushl %%ebx ;"			// here we go...
    		"popfl ;"
    		"xorl %%eax, %%eax ;"
    		"jmp fin ;"
    		".386: ;"
    		"movl $1, %%eax ;"
    		"fin: ;"
    		: "=a" (ret)
    		:
    		: "%ebx");
    	return ret;
    }
    Bien entendu, renvoir TRUE si ca en est un.
    Vu que tu utilises certainnement windows ou linux, tu est en mode protègé donc si ca ne supporte pas cpuid et que c'est pas un 386, c'est forcément un 486.

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Août 2002
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 8
    Par défaut
    Ensuite.
    Si cpuid est supporté,
    tu veut certainnement savoir qui a fabriqué cette gentille puce hein ?
    hehehe
    alors tu fait ca:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    int eax_value
    long returned_eax, returned_ebx, returned_ecx, returned_edx;
     
    		eax_value = 0;
    		asm(
    			"cpuid ;"
    			: "=b" (returned_ebx), "=c" (returned_ecx), "=d" (returned_edx)
    			: "a" (eax_value)
    			: "%ebp");
    ...

    Tout ca, ca va gentillement te mettre le nom du constructeur dans returned_eax, returned_ebx, returned_ecx, returned_edx;
    comment les recuperer ?
    hehe
    simple: tu crée un fonction dword_to_char()
    comme ca:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    char dword_to_char(DWORD data, int number)
    {
    	char re;
     
    	switch(number)
    	{
    		case 1:
    			re = (data & 0xFF);
    			break;
    		case 2:
    			re = (data >> 8);
    			break;
    		case 3:
    			re = (data >> 16);
    			break;
    		case 4:
    			re = (data >> 24);
    			break;
    		default:
    			re = 0x00;
     
    	};
    	return re;
    }
    apres, ca devient un jeu.

    dans la fonction ou tu as recuperé returned .......
    il faut simplement que tu declares ca:
    ensuites, tu fait ca:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    vendor_id[0] = dword_to_char( returned_ebx, 1);
    vendor_id[1] = dword_to_char( returned_ebx, 2);
    vendor_id[2] = dword_to_char( returned_ebx, 3);
    vendor_id[3] = dword_to_char( returned_ebx, 4);
    vendor_id[4] = dword_to_char( returned_edx, 1);
    vendor_id[5] = dword_to_char( returned_edx, 2);
    vendor_id[6] = dword_to_char( returned_edx, 3);
    vendor_id[7] = dword_to_char( returned_edx, 4);
    vendor_id[8] = dword_to_char( returned_ecx, 1);
    vendor_id[9] = dword_to_char( returned_ecx, 2);
    vendor_id[10] = dword_to_char( returned_ecx, 3);
    vendor_id[11] = dword_to_char( returned_ecx, 4);
    Voila !!
    finalisons
    vendor_id n'a plus qu'a ètre comparé a ca :

    "GenuineIntel"; // Intel
    "AuthenticAMD"; // AMD
    "AMD ISBETTER"; // Devines
    "CyrixInstead"; // Cyrix
    "NexGenDriven"; // NexGen
    "CentaurHauls"; // IDT/Centaur now via
    "RiseRiseRise"; // Rise
    "GenuineTMx86"; // Transmeta
    "UMC UMC UMC "; // United Microelectronics Corp.

    Voila, j'espère avoir été clair
    salut :p

    /l33t :p

  4. #4
    Membre confirmé
    Inscrit en
    Mai 2002
    Messages
    117
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 117
    Par défaut
    OK, merci pour tout ca, j'ai pas le temps d'essayer aujourd'hui. Pour le cpuid, le début de code que j'avais le faisait non ? S'il le fait, je veux juste récupérer l'ID du processeur, c'est pour ca que j'avais rajouté maladroitement cette ligne avant la fin mov IDProc, &0xa2, &0xa2 devant être l'adresse de l'ID, non ?

    En tout cas merci pour ce que tu m'as donné, mais ma question de départ n'est pas résolue, comment récupérer l'ID ??

    Merci encore.

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Août 2002
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 8
    Par défaut
    ID ??? que veut tu dire ?
    le modele ?

  6. #6
    Membre confirmé
    Inscrit en
    Mai 2002
    Messages
    117
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 117
    Par défaut
    Le numéro d'identification du processeur, pour ceux qui en ont bien sur, et il semblerait que seuls les intel aient un numéro unique ?? bizarre ...

    En fait depuis le débuut ce que je veux c'est récupérer ce numéro unique simplement pour verrouiller les utilisations sans license d'une appli.

    Merci 0x0F0-0FF (c'est l'adresse de qqch en particulier ou juste pour faire parler les zuzu trop curieux ???)

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Août 2002
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 8
    Par défaut
    Ahhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh !!!
    Le numéro de série intel !!!!!!
    okay, c'est un chiffre codé sur 96 bits.

    Cette information n'est apparement disponible que sur les pentium 2 et 3
    si tu est autorisé a l'avoir !!!!!

    déja, on va déterminer si tu est autoridé a l'avoir:

    Code nasm (je hais tasm et masm)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    [BITS 32]
    [SECTION .text]
     
    	jmp start
    start:
     
    	mov eax, 1
    	cpuid
    	shr edx, 0x12   ; Je récupere le bit 18, soit, PSN
    	and edx, 1	  ; je prends que celui la :p
     
    	cmp edx, is_ok
    	mov eax, edx	  ; Voila, si eax = 0, alors, tu peut
                   	  ; pas aller plus loin
    			  ; si eax = 1, c'est bon	
     
    [SECTION .data]
    is_ok db 1
    Voila pour la partie "est-ce que j'ai le droit ?"
    maintenant, si on a le droit, on prend le numéro:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    [BITS 32]
    [SECTION .text]
     
    	mov eax, 1
    	cpuid
    	mov [serial], eax
     
    	mov eax, 3
    	cpuid
    	mov [serial + 32], edx
    	mov [serial + 64], ecx
     
     
    [SECTION .data]
    serial 96 db 0
    Voila voila ))
    serial est comme tu l'as compris, le numéro de série
    mais comme je te l'ai dit, ca, ca ne passe que sur PII et PII. (PIV ?????)

    SI et seulement SI le bit PSN ets a 1
    M'enfin, j'espere t'avoir aider
    cya

    (Si tu as encore des pépins, http://developper.intel.com
    et tu recherche "cpuid")
    bye bye

  8. #8
    Membre confirmé
    Inscrit en
    Mai 2002
    Messages
    117
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 117
    Par défaut
    Ok, merci beaucoup !!

  9. #9
    Invité de passage
    Inscrit en
    Mai 2008
    Messages
    1
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1
    Par défaut
    desole de deterrer un si vieux topic, mais j'ai besoin de recuperer serial ou vendor_id aussi.

    Seulement mon soucis, c'est que pour certaines raisons, je code imperativement sous dos, et l'utilisation des registres 32 bits ne semble pas etre supportee (ce qui reste logique sous dos).

    J'aimerais savoir s'il est possible de realiser les memes fonctions en se limitant au registres 16 bits ?

    Sous dos je compile avec Turbo ( c++ et tasm ), desole pour ceux qui n'aiment pas mais y a pas d'autre choix.

    desole aussi pour l'ecriture, mais on ne trouve que des claviers qwerty en roumanie et j'ai la fleme d'installer une police francaise...

  10. #10
    Membre chevronné Avatar de dapounet
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2007
    Messages
    469
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2007
    Messages : 469
    Par défaut
    Citation Envoyé par kos38 Voir le message
    Seulement mon soucis, c'est que pour certaines raisons, je code imperativement sous dos, et l'utilisation des registres 32 bits ne semble pas etre supportee (ce qui reste logique sous dos).
    Si ça marche, il faut juste que ton assembleur/compilateur sache qu'il doit écrire du code 16 bits (avec TASM ça ne devrait pas être difficile).

Discussions similaires

  1. Déterminer la Valeur la plus grande dans une table
    Par arnaud_verlaine dans le forum Langage SQL
    Réponses: 9
    Dernier message: 22/08/2014, 23h35
  2. Déterminer la position de la souris
    Par genteur slayer dans le forum Composants VCL
    Réponses: 6
    Dernier message: 16/06/2003, 11h01
  3. Réponses: 5
    Dernier message: 25/03/2003, 17h27
  4. déterminer la version de Winsock installée
    Par BlueX_scf dans le forum Web & réseau
    Réponses: 7
    Dernier message: 24/02/2003, 10h23
  5. Déterminer l'adresse d'une application en mémoire
    Par Gib dans le forum x86 32-bits / 64-bits
    Réponses: 9
    Dernier message: 11/06/2002, 14h27

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo