
CPUInfos:
	pushad
	pushfd 			; Sauve le registre EFLAGS
	pop eax 		; Le récupère dans EAX
	mov ebx, eax 	; Le copie dans EBX pour la comparaison postérieure
	xor eax, 0x200000 ; on change l'état du bit 21
	push eax 		; On le met sur la pile
	popfd 			; Pour le remettre dans le registre EFLAGS
	pushfd 			; On re-sauve le registre EFLAGS (c'est l'idée du test)
	pop eax 		; Le récupère dans EAX
	cmp eax, ebx 	; Et on le compare avec sa sauvegarde
	jz .NO_CPUID 	; Si rien n'a changé, l'instruction CPUID n'est pas supportée.
;;Fonction 0 : Nombre de fonctions disponibles et marque
	xor eax, eax
	cpuid
	mov [nbFonctions], eax
	mov edi, chaine	;Affichage de la marque
	mov eax, ebx
	stosd
	mov eax, edx
	stosd
	mov eax, ecx
	stosd
	xor al, al
	stosb
	mov esi, chaine
	call conversionASCII ;Vi, elle est donnée en ASCII.
	call afficheChaine
	call retourChariot
	xor eax, eax
;Force la marque
;	mov ebx, 0x68747541
	cmp [Intel.ebx], ebx ; On traite les 2 marques gérées
	je .marqueIntel
	cmp [AMD.ebx], ebx
	je .marqueAMD
.marqueInconnue:
	mov byte [Marque], al
	call chargeCPUIDFamille ; On charge les familles de processeurs du constructeur

	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	;; Affichage du nombre de fonctions ;;
	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	mov esi, chNbFonctions ; Du texte
	call afficheChaine
	mov eax, [nbFonctions]
	mov edi, chaine
	mov esi, edi
	mov ebx, 10
	xor ecx, ecx
	call nombreVersChaine
	mov ax, 112
	stosw
	call afficheChaine

;;Fonction 1
	mov eax, 1
	cmp eax, [nbFonctions]
	jae .fin ; La fonction n'existe pas
	cpuid
	shr eax, 4
	mov ebx, eax
	and ebx, 0xF
	mov [Modele], bl
	shr eax, 4
	mov [Famille], al
	and eax, 0xF
	call chargeCPUIDModele
	shl eax, 2
	add eax, listeFamilles
	mov esi, [eax]
	call afficheChaine
	call retourChariot
	xor eax, eax
	mov al, [Modele]
	shl eax, 2
	add eax, pFamilles
	mov esi, [eax]
	call afficheChaine
	call retourChariot
.fin:
	
.NO_CPUID:
	popad
	ret

.marqueAMD:
	inc al; AL = 2
.marqueIntel:
	inc al; AL = 1
	jmp .marqueInconnue

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; EAX contient la marque du CPU, et est détruit ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
chargeCPUIDFamille:
	push edi
	push ecx

	mov edi, listeFamilles
	mov ecx, 16
	cmp al, 1 ;Test Intel
	je .setEAXIntel2
	cmp al, 2 ;Test AMD
	je .setEAXAMD2
.suite:
	call chargeListeSansTest
	pop ecx
	pop edi
	ret

.setEAXIntel2:
	mov eax, Intel.Familles
	jmp .suite

.setEAXAMD2:
	mov eax, AMD.Familles
	jmp .suite

;; Cette fonction met à jour une liste d'index de chaines de caractères.
;; Si cette liste n'est pas vide, elle rend la main.
;; ECX contient le nombre de chaînes à indexer
;; EAX contient l'adresse de la liste des chaînes
;; EDI contient l'adresse de la liste d'index à mettre à jour
chargeListe:
	test [edi + 1], byte 0xFF
	jnz chargeListeSansTest.retour
chargeListeSansTest:
	push eax
	push ebx
	mov ebx, eax
.chaineSuivante:
	stosd
	push ecx
	xchg edi, ebx
	xor al, al
	or ecx, 0xFFFFFFFF
	repne scasb
	mov eax, edi
	xchg edi, ebx
	pop ecx
	loop .chaineSuivante
	pop ebx
	pop eax
.retour:
	ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; EAX contient la famille du CPU ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
chargeCPUIDModele:
	push edi
	push eax
	push ecx
	mov al, [Marque]
	cmp al, 1 ;Test Intel
	je .setEAXIntel
	cmp al, 2 ;Test AMD
	je .setEAXAMD
.chargement:
	mov edi, eax
	mov eax, 0x10
	mul byte [Famille]
	mov ecx, eax
	xor eax, eax
	;EAX contient 0, EDI contient l'adresse du modèle 0 de la famille 0
.bouclePointeurs:
	push ecx
	or ecx, 0xFFFFFFFF
	repne scasb
	pop ecx
	loop .bouclePointeurs
	xchg edi, eax
	;EDI contient 0, EAX contient l'adresse du modèle 0 de la famille I
	mov edi, pFamilles
	mov ecx, 0x10
	call chargeListeSansTest
	pop ecx
	pop eax
	pop edi
	ret
	
.setEAXIntel:
	mov eax, Intel.Modeles0
	jmp .chargement

.setEAXAMD:
	mov eax, AMD.Modeles0
	jmp .chargement

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Données pour bien utiliser CPUID 			;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
chNbFonctions: 	db 97, 25, 23, 12, 28, 15, 51, 14, 15, 51, 16, 25, 24, 13, 30, 19, 25, 24, 29, 51, 14, 25, 24, 30, 51, 14, 19, 29
				db 26, 25, 29, 15, 51, 86, 99,104, 92, 87, 51, 45, 51,  0 
; "Nombre de fonctions dont dispose CPUID : "
nbFonctions: 	dd 0
Marque:		db 0
Famille: 	db 0
Modele: 	db 0
listeFamilles: 	dd 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0	;Adresses des noms des familles
pFamilles:		dd 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0	;Adresses des noms des modèles
Intel:
.ebx:	dd 0x756E6547
.Familles:
.Inconnu: db 92, 24, 13, 25, 24, 24, 31,  0;"Inconnu"
db 0, 0, 0
db 5,9,7,0;"486"
db 99, 15, 24, 30, 19, 31, 23,  0; "Pentium"
db  92, 24, 30, 15, 22, 51, 99,  7, 43, 51, 99,  3, 43, 51, 99,  4, 43, 51, 99, 96, 43, 51, 86, 25, 28, 15, 51,  3,  0
; "Intel P6, P2, P3, PM, Core 2"
;db 99, 15, 24, 30, 19, 31, 23, 51, 15, 30, 51, 29, 31, 26, 15, 28, 19, 15, 31, 28,  0; "Pentium et supérieur"
db 0, 0, 0, 0, 0, 0, 0, 0
db 99, 15, 24, 30, 19, 31, 23,  5,  0; "Pentium4"
.Modeles0:
db 1, 0
db 1, 0
db 2, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.Modeles1:
db 2, 0
db 2, 0
db 3, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.Modeles2:
db 3, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.Modeles3:
db 4, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.Modeles4:
db 5, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.Modeles5:
db 6, 0
db 99, 15, 24, 30, 19, 31, 23,  0; "Pentium"
db 99, 15, 24, 30, 19, 31, 23,  0; "Pentium"
db 0
db 99, 15, 24, 30, 19, 31, 23, 51, 96, 96,107,  0; "Pentium MMX"
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.Modeles6:
db  99,  7, 51, 84, 64, 29, 30, 15, 26,  0; "P6 A-step"
db  99,  7,  0; "P6"
;db  99, 15, 24, 30, 19, 31, 23, 51, 99, 28, 25,  0; "Pentium Pro"
db  0
db  99, 15, 24, 30, 19, 31, 23, 51, 92, 92, 51, 79,  1, 43,  3,  9, 51,115, 23,114,  0; "Pentium II (0,28 µm)"
db  0
db  99, 15, 24, 30, 19, 31, 23, 51, 92, 92, 51, 79,  1, 43,  3,  6, 51,115, 23,114,  0; "Pentium II (0,25 µm)"
db  99, 15, 24, 30, 19, 31, 23, 51, 92, 92, 51, 33, 19, 30, 18, 51, 25, 24, 64, 14, 19, 15, 51, 95, 3, 51
db  13, 11, 13, 18, 15,  0; "Pentium II with on-die L2 cache"
;db 86, 15, 22, 15, 28, 25, 24,  0; "Celeron"
db  99, 15, 24, 30, 19, 31, 23, 51, 92, 92, 92, 51, 79,  1, 43,  3,  6, 51,115, 23,114,  0; "Pentium III (0,25 µm)"
db  99, 15, 24, 30, 19, 31, 23, 51, 92, 92, 92, 51, 79,  1, 43,  2,  9, 51,115, 23,114, 51
db  33, 19, 30, 18, 51,  3,  6,  7, 94, 85, 51, 25, 24, 64, 14, 19, 15, 51, 95,  3,  0; "Pentium III (0,18 µm) with 256 KB on-die L2"
db  99, 15, 24, 30, 19, 31, 23, 51, 96, 51, 79,  1, 43,  2,  4, 51,115, 23,114, 51
db  33, 19, 30, 18, 51,  1, 96, 85, 51, 25, 24, 64, 14, 19, 15, 51, 95,  3, 51, 79, 85, 11, 24, 19, 11, 29, 114,  0; 
;"Pentium M (0.13 µm) with 1 MB on-die L2 (Banias)"
;db  99, 15, 24, 30, 19, 31, 23, 51, 96, 51, 25, 31, 51, 86, 15, 22, 15, 28, 25, 24, 51, 96,  0; "Pentium M ou Celeron M"
db  99, 15, 24, 30, 19, 31, 23, 51, 92, 92, 92, 51,107, 15, 25, 24,  0; "Pentium III Xeon"
db  99, 15, 24, 30, 19, 31, 23, 51, 92, 92, 92,  0; "Pentium III"
db  0
db  99, 15, 24, 30, 19, 31, 23, 51, 96, 51, 25, 31, 51, 86, 15, 22, 15, 28, 25, 24, 51, 96,  0; "Pentium M ou Celeron M"
db  86, 25, 28, 15, 0;"Core"
db 86, 25, 28, 15, 51, 3, 0;"Core 2"
.Modeles7:
db 8, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.Modeles8:
db 9, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.Modeles9:
db 10, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.ModelesA:
db 11, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.ModelesB:
db 12, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.ModelesC:
db 13, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.ModelesD:
db 14, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.ModelesE:
db 15, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.ModelesF:
db 16, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
AMD:
.ebx:	dd 0x68747541
.Familles:
db 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8, 0, 9, 0, 10, 0, 11, 0, 12, 0, 13, 0, 14, 0, 15, 0, 16, 0
.Modeles0:
db 1, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.Modeles1:
db 2, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.Modeles2:
db 3, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.Modeles3:
db 4, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.Modeles4:
db 5, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.Modeles5:
db 6, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.Modeles6:
db 7, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.Modeles7:
db 8, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.Modeles8:
db 9, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.Modeles9:
db 10, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.ModelesA:
db 11, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.ModelesB:
db 12, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.ModelesC:
db 13, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.ModelesD:
db 14, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.ModelesE:
db 15, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.ModelesF:
db 16, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
