IDEAL

MODEL SMALL

P386

PUBLIC	_getcpu

CODESEG

PROC	_getcpu	 NEAR

; --------------------------------------------------------
; Пытаемся установить старшую тетраду регистра флагов в 0.
; Если программа работает на процессоре 8086, в этом
; байте все биты будут установлены в 1
; --------------------------------------------------------

	mov     dx, 86	; Тип процессора - 8086

	pushf
	pop     bx
	and     bh,0Fh
	push    bx
	popf
	pushf
	pop     ax
	and     ah,0F0h
	cmp     ah,0F0h
	je      cpu_end

; --------------------------------------------------------
; Для теста на процессор 80286 пытаемся установить старшую
; тетраду регистра флагов в единицы. Если программа
; выполняется на процессоре 80286, эти биты останутся
; равными нулю
; --------------------------------------------------------

	mov     dx, 286		; Тип процессора - 80286

	or      bh,0F0h
	push    bx
	popf
	pushf
	pop     ax
	test    ah,0F0h
	jz      cpu_end

; --------------------------------------------------------
; Для того, чтобы отличить процессор 80386 от процессора
; 80486, используем бит 18 регистра флагов EFLAGS.
; Если программа может изменить состояние этого бита,
; она выполняется на процессоре 80486. В противном случае
; используется процессор 80386.
; --------------------------------------------------------

; Созраняем указатель стека

	mov     edx,esp

; Выравниваем указатель стека для предотвращения
; исключения при установке флага AC

	and     esp,not 3

; Копируем регистр EFLAGS в регистр EAX

	pushfd
	pop     eax

; Сохраняем начальное значение регистра EFLAGS

	mov     ecx,eax

; Переключаем флаг AC

	xor     eax,40000H

; Пытаемся записать измененное значение обратно в регистр
; EFLAGS

	push     eax
	popfd

; Копируем регистр EFLAGS в регисрр EAX

	pushfd
	pop     eax

; Сравниваем старое и новое значения бита AC

	xor     eax,ecx
	shr     eax,18
	and     eax,1
	push    ecx

; Восстанавливаем регситр EFLAGS

	popfd

; Восстанавливаем указатель стека

	mov     esp,edx

; Теперь если программа выполняется на процессоре 80386,
; регистр AX содержит значение 0, а если на процессоре
; 80486 - значение 1.

	mov     dx,386		; Тип процессора - 80386

	test    ax,ax
	jz      cpu_end

	mov     ax,486		; Тип процессора - 80486

cpu_end:
	mov	ax, dx
	ret
ENDP	_getcpu

END