Skip to content

Instantly share code, notes, and snippets.

@ljmccarthy
Last active March 30, 2019 07:14
Show Gist options
  • Select an option

  • Save ljmccarthy/e87d0e0b028413fad3317ad80e9e4db1 to your computer and use it in GitHub Desktop.

Select an option

Save ljmccarthy/e87d0e0b028413fad3317ad80e9e4db1 to your computer and use it in GitHub Desktop.
Detect x86 CPU Type (8086, i286, i386, i486, Pentium, Pentium Pro)
format MZ
entry main:start
use16
segment main
start:
call detect_cpu
mov dx, strings
mov ds, dx
mov bx, ax
lea bx, [strings.cpu_string_table - 1 + bx]
xor dx, dx
mov dl, byte [bx]
mov ah, 0x09
int 0x21
mov ax, 0x4c00
int 0x21
detect_cpu:
push bp
mov bp, sp ; save SP
pushf ; save FLAGS
mov ax, 1
; clear FLAGS register
xor cx, cx
push cx
popf
pushf
pop cx
; test if top 2 bits (NT, reserved) are set
test cx, 0xc000
jnz .exit_popf
inc ax
; set NT and IOPL flags
mov cx, 0x7000
push cx
popf
pushf
pop cx
; test if NT and IOPL are still set
test ch, 0x70
jz .exit_popf
inc ax
popf ; restore FLAGS
and sp, 0xfffc ; align stack
pushfd ; save EFLAGS
; set the AC bit
pushfd
pop ecx
mov edx, 0x40000
or ecx, edx
push ecx
popfd
pushfd
pop ecx
test ecx, edx
jz .exit_popfd
inc ax
; toggle ID bit to check for CPUID
mov edx, ecx
xor ecx, 0x200000
push ecx
popfd
pushfd
pop ecx
cmp edx, ecx
je .exit_popfd
popfd ; restore EFLAGS
; use CPUID
mov eax, 1
cpuid
shr ax, 8
and ax, 0xf
cmp al, 4
jb .min_family
cmp al, 6
ja .max_family
jmp .exit
.min_family:
mov al, 4
jmp .exit
.max_family:
mov al, 6
jmp .exit
.exit_popfd:
popfd
jmp .exit
.exit_popf:
popf
.exit:
mov sp, bp ; restore SP
pop bp
ret
segment strings
.cpu_string_table:
db .cpu_8086
db .cpu_i286
db .cpu_i386
db .cpu_i486
db .cpu_pentium
db .cpu_pentiumpro
.cpu_8086: db "8086$"
.cpu_i286: db "i286$"
.cpu_i386: db "i386$"
.cpu_i486: db "i486$"
.cpu_pentium: db "Pentium$"
.cpu_pentiumpro: db "Pentium Pro$"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment