;; Author: spin
;; Licence: vodkaware (pareil que la beerware mais avec de la vodka à la place)
;; assemblez simplement avec la commande : $ fasm cefichier.asm
;; puis c'est tout
format ELF executable 3
entry start
; .text
segment readable executable
start:
mov eax, 4 ;; print welcome message
mov ebx, 1
mov ecx, msg
mov edx, 24
int $80
mov eax, 4 ;; print CPU vendor
mov ebx, 1
mov ecx, uc
mov edx, 16
int $80
mov eax, 0 ;; get vendor ID
cpuid
push $0a ; '\n'
push ecx
push edx
push ebx
mov eax, 4 ;; print vendor ID
mov ebx, 1
mov ecx, esp
mov edx, 13
int $80
;***********[ check extensions ]***********;
mov eax, 4 ;; print "> Extensions:"
mov ebx, 1
mov ecx, ext
mov edx, 15
int $80
mov eax, 4 ;; check x87 FPU
mov ebx, 1
mov ecx, x87
mov edx, 11
int $80
mov eax, 1
cpuid
bt edx, 0
call check
mov eax, 4 ;; check MMX
mov ebx, 1
mov ecx, mmx
mov edx, 11
int $80
mov eax, 1
cpuid
bt edx, 23
call check
mov eax, 4 ;; check SSE
mov ebx, 1
mov ecx, sse
mov edx, 11
int $80
mov eax, 1
cpuid
bt edx, 25
call check
mov eax, 4 ;; check SSE2
mov ebx, 1
mov ecx, sse2
mov edx, 11
int $80
mov eax, 1
cpuid
bt edx, 26
call check
mov eax, 4 ;; check SSE3
mov ebx, 1
mov ecx, sse3
mov edx, 11
int $80
mov eax, 1
cpuid
bt ecx, 0
call check
mov eax, 4 ;; check SSSE3
mov ebx, 1
mov ecx, ssse3
mov edx, 11
int $80
mov eax, 1
cpuid
bt ecx, 9
call check
mov eax, 4 ;; check SSE4.1
mov ebx, 1
mov ecx, sse41
mov edx, 11
int $80
mov eax, 1
cpuid
bt ecx, 19
call check
mov eax, 4 ;; check SSE4.2
mov ebx, 1
mov ecx, sse42
mov edx, 11
int $80
mov eax, 1
cpuid
bt ecx, 20
call check
mov eax, 4 ;; check AVX
mov ebx, 1
mov ecx, avx
mov edx, 11
int $80
mov eax, 1
cpuid
bt ecx, 28
call check
;; check AES
mov eax, 4
mov ebx, 1
mov ecx, aes
mov edx, 11
int $80
mov eax, 1
cpuid
bt ecx, 25
call check
;***********[ check instructions ]***********;
mov eax, 4 ;; print "> Instructions:"
mov ebx, 1
mov ecx, inst
mov edx, 17
int $80
mov eax, 4 ;; check RDRAND
mov ebx, 1
mov ecx, rand
mov edx, 11
int $80
mov eax, 1
cpuid
bt ecx, 30
call check
mov eax, 4 ;; check CMPXCHG16B
mov ebx, 1
mov ecx, cmp16
mov edx, 11
int $80
mov eax, 1
cpuid
bt ecx, 13
call check
mov eax, 4 ;; check MOVBE
mov ebx, 1
mov ecx, movb
mov edx, 11
int $80
mov eax, 1
cpuid
bt ecx, 22
call check
mov eax, 4 ;; check POPCNT
mov ebx, 1
mov ecx, ppcnt
mov edx, 11
int $80
mov eax, 1
cpuid
bt ecx, 23
call check
mov eax, 4 ;; check PCLMULQDQ
mov ebx, 1
mov ecx, pcldq
mov edx, 11
int $80
mov eax, 1
cpuid
bt ecx, 1
call check
mov eax, 4 ;; check CX8
mov ebx, 1
mov ecx, c8
mov edx, 11
int $80
mov eax, 1
cpuid
bt edx, 8
call check
mov eax, 4 ;; check CMOV
mov ebx, 1
mov ecx, cmv
mov edx, 11
int $80
mov eax, 1
cpuid
bt edx, 15
call check
mov eax, 4 ;; check CFLESH
mov ebx, 1
mov ecx, clsh
mov edx, 11
int $80
mov eax, 1
cpuid
bt edx, 19
call check
mov eax, 4 ;; check FXSR
mov ebx, 1
mov ecx, fsr
mov edx, 11
int $80
mov eax, 1
cpuid
bt edx, 24
call check
mov eax, 1 ;; EXIT 0
xor ebx, ebx
int $80
ok: mov eax, 4
mov ebx, 1
mov ecx, yes
mov edx, 2
int $80
ret
nok: mov eax, 4
mov ebx, 1
mov ecx, no
mov edx, 2
int $80 ;; write vendor ID
ret
check: jnc nok
jc ok
; .data
segment readable writeable
msg: db "0x0fa2 (cpuid) checker", $0a, $0a ;; 24
uc: db "> CPU vendor: " ;; 16
ext: db $0a, "> Extensions:", $0a ;; 15
inst:db $0a, "> Instructions:", $0a ;; 17
x87: db "x87 FPU " ;; 11 chars
mmx: db "MMX "
sse: db "SSE "
sse2: db "SSE2 "
sse3: db "SSE3 "
ssse3: db "SSSE3 "
sse41: db "SSE4.1 "
sse42: db "SSE4.2 "
avx: db "AVX "
aes: db "AES "
rand: db "RDRAND " ;; here starts instructions strings
cmp16: db "CMPXCHG16B "
movb: db "MOVBE "
ppcnt: db "POPCNT "
pcldq: db "PCLMULQDQ "
c8: db "CX8 "
cmv: db "CMOV "
clsh: db "CLFSH "
fsr: db "FXSR "
no: db "0", $0a
yes: db "1", $0a
spin