SECTION .text USE16 cpuid_required_features: .edx equ cpuid_edx.fpu | cpuid_edx.pse | cpuid_edx.pge | cpuid_edx.fxsr .ecx equ 0 cpuid_check: ; If bit 21 of EFLAGS can be changed, then CPUID is supported pushfd ;Save EFLAGS pushfd ;Store EFLAGS xor dword [esp],0x00200000 ;Invert the ID bit in stored EFLAGS popfd ;Load stored EFLAGS (with ID bit inverted) pushfd ;Store EFLAGS again (ID bit may or may not be inverted) pop eax ;eax = modified EFLAGS (ID bit may or may not be inverted) xor eax,[esp] ;eax = whichever bits were changed popfd ;Restore original EFLAGS test eax,0x00200000 ;eax = zero if ID bit can't be changed, else non-zero jz .no_cpuid mov eax, 1 cpuid and edx, cpuid_required_features.edx cmp edx, cpuid_required_features.edx jne .error and ecx, cpuid_required_features.ecx cmp ecx, cpuid_required_features.ecx jne .error ret .no_cpuid: mov si, .msg_cpuid call print mov si, .msg_line call print jmp .halt .error: push ecx push edx mov si, .msg_features call print mov si, .msg_line call print mov si, .msg_edx call print pop ebx push ebx shr ebx, 16 call print_hex pop ebx call print_hex mov si, .msg_must_contain call print mov ebx, cpuid_required_features.edx shr ebx, 16 call print_hex mov ebx, cpuid_required_features.edx call print_hex mov si, .msg_line call print mov si, .msg_ecx call print pop ebx push ebx shr ebx, 16 call print_hex pop ebx call print_hex mov si, .msg_must_contain call print mov ebx, cpuid_required_features.ecx shr ebx, 16 call print_hex mov ebx, cpuid_required_features.ecx call print_hex mov si, .msg_line call print .halt: cli hlt jmp .halt .msg_cpuid: db "CPUID not supported",0 .msg_features: db "Required CPU features are not present",0 .msg_line: db 13,10,0 .msg_edx: db "EDX ",0 .msg_ecx: db "ECX ",0 .msg_must_contain: db " must contain ",0 cpuid_edx: .fpu equ 1 << 0 .vme equ 1 << 1 .de equ 1 << 2 .pse equ 1 << 3 .tsc equ 1 << 4 .msr equ 1 << 5 .pae equ 1 << 6 .mce equ 1 << 7 .cx8 equ 1 << 8 .apic equ 1 << 9 .sep equ 1 << 11 .mtrr equ 1 << 12 .pge equ 1 << 13 .mca equ 1 << 14 .cmov equ 1 << 15 .pat equ 1 << 16 .pse_36 equ 1 << 17 .psn equ 1 << 18 .clfsh equ 1 << 19 .ds equ 1 << 21 .acpi equ 1 << 22 .mmx equ 1 << 23 .fxsr equ 1 << 24 .sse equ 1 << 25 .sse2 equ 1 << 26 .ss equ 1 << 27 .htt equ 1 << 28 .tm equ 1 << 29 .ia64 equ 1 << 30 .pbe equ 1 << 31 cpuid_ecx: .sse3 equ 1 << 0 .pclmulqdq equ 1 << 1 .dtes64 equ 1 << 2 .monitor equ 1 << 3 .ds_cpl equ 1 << 4 .vmx equ 1 << 5 .smx equ 1 << 6 .est equ 1 << 7 .tm2 equ 1 << 8 .ssse3 equ 1 << 9 .cnxt_id equ 1 << 10 .sdbg equ 1 << 11 .fma equ 1 << 12 .cmpxchg16b equ 1 << 13 .xtpr equ 1 << 14 .pdcm equ 1 << 15 .pcid equ 1 << 17 .dca equ 1 << 18 .sse4_1 equ 1 << 19 .sse4_2 equ 1 << 20 .x2apic equ 1 << 21 .movbe equ 1 << 22 .popcnt equ 1 << 23 .tsc_deadline equ 1 << 24 .aes equ 1 << 25 .xsave equ 1 << 26 .osxsave equ 1 << 27 .avx equ 1 << 28 .f16c equ 1 << 29 .rdrand equ 1 << 30 .hypervisor equ 1 << 31