Главная | Обратная связь | Поможем написать вашу работу!
МегаЛекции

mov cx, ax. and ax, 0fffh. push ax. and ax, 0f000h. cmp ax, 0f000h. Модель Intel 80286. mov ax, 0f000h. Потом программа проверят, изменилось ли содержимое указанных битов регистра FLAGS




mov cx, ax

Далее программа пытается записать нулевые значения в биты 12-15 регистра FLAGS:

and ax, 0fffh

push ax

popf      

Потом программа проверят, изменилось ли содержимое указанных битов регистра FLAGS. Для этого новое содержимое регистра FLAGS записывается через стек в регистр AX, а затем, после наложения маски 0f000h, сравнивается со значением 0f000h:

pushf

pop ax

and ax, 0f000h

cmp ax, 0f000h

je is_8086

Если биты 12-15 остались установленными в единичное значение, программа работает на процессоре Intel 8086/8088, если нет – в компьютере установлена более старшая модель процессора.

Модель Intel 80286

 

В данном процессоре, когда он работает в реальном режиме адресации, биты 12-15 регистра FLAGS всегда сброшены в нуль, что можно использовать для обнаружения этой модели процессора.

Следующий фрагмент кода пытается записать в эти биты единичное значение:

mov ax, 0f000h

push ax

popf

Затем новое содержимое регистра FLAGS переписывается в регистр AX:

pushf

pop ax

Если содержимое битов 12-15 равно нулю, программа работает на процессоре Intel 80286:

and ax, 0f000h

jz is_80286

В противном случае необходимо продолжить проверку модели процессора.

Модель Intel 80386

 

Для того чтобы отличить этот процессор от процессоров старших моделей, можно попробовать установить в регистре EFLAGS бит 18. Этот бит был впервые определен в процессоре Intel 80486 для сигнализации ошибки выравнивания. Его невозможно установить в процессоре Intel 80386.

В процессе проверки программа вначале получает исходное содержимое регистра EFLAGS, записывая его в регистры EAX и ECX:

pushfd

pop eax

mov ecx, eax

Далее программа инвертирует значение бита 18 и записывает полученный результат в регистр EFLAGS:

xor eax, 40000h

push eax

popfd

На последнем шаге идентификации новое содержимое регистра EFLAGS извлекается и сравнивается со старым:

pushfd

pop eax

xor eax, ecx

jz is_80386

Если бит 18 не изменил своего значения, мы имеем дело с процессором Intel 80386.

Модель Intel 80486

 

Отличительная особенность этого процессора – невозможность изменения состояния бита 21 регистра EFLAGS. Этот бит используется процессорами Intel Pentium и более старшими моделями процессоров Intel для определения возможности вызова команды идентификации процессора CPUID.

Фрагмент кода, который нужно использовать для обнаружения процессора Intel 80486, аналогичен фрагменту для процессора Intel 80386. Отличие заключается в том, что вместо бита 18 проверяется бит 21:

pushfd

pop eax

mov ecx, eax

xor eax, 200000h

push eax

popfd

pushfd

pop eax

xor eax, ecx

je is_80486

Если же выяснилось, что содержимое бита 21 регистра EFLAGS можно изменять, дальнейшую идентификацию модели процессора следует выполнять с использованием команды CPUID.

Команда CPUID

 

В новых процессорах фирмы Intel появилась команда CPUID, специально предназначенная для определения модели процессора. В программе можно определить эту команду следующим образом:

 

CPU_ID MACRO

db 0fh

db 0a2h

ENDM

 

Перед вызовом этой команды необходимо загрузить в регистр EAX значение, которое определяет выполняемые действия. В первый раз нужно вызвать команду CPUID, загрузив предварительно в регистр EAX нулевое значение:

mov eax, 00h

CPU_ID

Команда вернет в регистре EAX максимальное значение, которое можно передавать команде CPUID для определения выполняемых действий. Кроме того, в регистрах EBX, ECX и EDX будут находиться байты текстовой строки описания фирмы-изготовителя процессора.

Следующая последовательность команд перепишет эти байты в буфер _vendor_id_msg в формате, пригодном для вывода на консоль средствами BIOS:

_vendor_id_msg db "............ ", 0dh, 0ah, " $"

. . .

mov dword ptr _vendor_id_msg, ebx

mov dword ptr _vendor_id_msg[+4], edx

mov dword ptr _vendor_id_msg[+8], ecx

Для определения модели процессора следует вызвать команду CPUID, загрузив предварительно в регистр EAX значение 1:

mov eax, 1

CPU_ID

При этом в регистр EAX будет загружено слово сигнатуры, по которому можно определить модель процессора, а в регистр EDX – слово, состоящее из отдельных флагов, характеризующих возможности процессора (feature flags). Регистры EBX и ECX зарезервированы для моделей процессоров, которые будут разработаны в будущем.

Ниже приведен фрагмент кода, в котором слово сигнатуры и слово возможностей записываются в переменные _cpu_signature и _features_edx для дальнейшего анализа:

_ cpu_signature dd 0

_features_edx dd 0

. . .

mov _cpu_signature, eax

mov _features_edx, edx

 

Рассмотрим формат слова сигнатуры, возвращаемое командой CPUID в регистре EAX:

 

Биты Описание
0-3 Код модификации модели (stepping)
4-7 Код модели
8-11 Код семейства моделей
12-13 Тип процессора
14-31 Зарезервировано

 

Биты 12 и 13 определяют тип процессора:

 

Значение битов 12 и 13 Тип процессора
Процессор, изготовленный производителем OEM
Процессор OverDrive
Процессор типа Dual, который можно использовать в двухпроцессорных системах
Зарезервировано

 

Таблица, с помощью которой по содержимому трех полей слова сигнатуры (тип процессора, код семейства и код модели) можно распознать процессор:

 

Тип процессора Код семейства Код модели Описание процессора
Intel 486 SL
Intel DX2
Intel DX4
00, 01 Intel DX4 OverDrive
Pentium 60, 66; Pentium OverDrive для процессоров Pentium 60, 66
Pentium 75, 90, 100, 120, 133, 150, 166, 200
Pentium OverDrive для процессоров Pentium 75, 90, 100, 120, 133
Pentium OverDrive для систем на базе процессора Intel 486
Pentium 166, 200 с командами MMX
Зарезервировано. Будет использоваться процессорами Pentium OverDrive для процессоров Pentium 75, 90, 100, 120, 133
Pentium Pro
Pentium II
Зарезервировано для новых процессоров P6
Зарезервировано для процессоров Pentium OverDrive для процессоров Pentium Pro

 

Биты, возвращаемых командой CPUID в регистре EDX (слово, состоящее из отдельных флагов, характеризующих возможности процессора).

 

Бит Описание
На кристалле процессора имеется арифметический сопроцессор, совместимый по командам с сопроцессором Intel 387
Процессор может работать в режиме виртуального процессора 8086
Процессор может работать с прерываниями ввода/вывода, а также с битом DE регистра CR4
Возможно использование страниц памяти размером 4 Мбайт
В процессоре есть команда RDTSC, которая может работать с битом TSD регистра CR4
Набор регистров процессора, специфический для модели, доступен с помощью команд RDMSR, WRMSR
Возможна физическая адресация памяти с использованием шины с шириной, большей чем 32 разряда
В процессоре реализовано исключение Machine Check (исключение с номером 18). Возможно использование бита MCE регистра CR4
В процессоре реализована команда сравнения и обмена 8 байт данных CMPXCHG8
В процессоре есть локальный APIC
Зарезервировано
В процессоре реализованы команды быстрого вызова системы SYSENTER и SYSEXIT
В процессоре есть регистры Memory Type Range
Доступен глобальный бит в PDE и PTE, а также бит PGE в регистре CR4
Применена архитектура Machine Check Architecture
В процессоре реализованы команды условного перемещения данных CMOVCC и (при установленном бите 0) FCMOVCC и FCOMI
16-22 Зарезервировано
Применена технология MMX
24-31 Зарезервировано

 


Пример:

 


; ==================================

; Get CPU information

; ==================================

. model small

CPU_ID MACRO

db 0fh

db 0a2h

ENDM

. stack 100h

. data

public _vendor_id_msg

public _cpu_model

public _cpu_signature

public _features_ecx

public _features_edx

public _features_ebx

public _get_cpu_model

_vendor_id_msg db "............ ", 0dh, 0ah, " $"

_cpu_model db 0

_cpu_signature dd 0

_features_ecx dd 0

_features_edx dd 0

_features_ebx dd 0

. code

; ==================================

; _get_cpu_model

; ==================================

. 8086

_get_cpu_model proc

call cpu_8086

cmp ax, 0

jz try_80286

mov _cpu_model, 0

jmp end_of_detect

try_80286:

call cpu_80286

cmp ax, 0

jz try_80386

mov _cpu_model, 2

jmp end_of_detect

try_80386:

call cpu_80386

cmp ax, 0

jz try_80486

mov _cpu_model, 3

jmp end_of_detect

try_80486:

call cpu_80486

cmp ax, 0

jz Pent_CPU

mov _cpu_model, 4

jmp end_of_detect

Pent_CPU:

mov _cpu_model, 5

. 386

pusha

mov eax, 00h

CPU_ID

mov dword ptr _vendor_id_msg, ebx

mov dword ptr _vendor_id_msg[+4], edx

mov dword ptr _vendor_id_msg[+8], ecx

cmp eax, 1

jl end_of_detect

mov eax, 1

CPU_ID

  mov _cpu_signature, eax

mov _features_ebx, ebx

mov _features_edx, edx

mov _features_ecx, ecx

popa

end_of_detect:

 

. 8086

ret

_get_cpu_model endp

; ==================================

; cpu_8086

; ==================================

cpu_8086 proc

pushf

pop ax

mov cx, ax

and ax, 0fffh

push ax

popf

pushf

pop ax

and ax, 0f000h

cmp ax, 0f000h

je is_8086

mov ax, 0

ret

is_8086:

mov ax, 1

ret

cpu_8086 endp

; ==================================

; cpu_80286

; ==================================

. 286

cpu_80286 proc

mov ax, 0f000h

push ax

popf

pushf

pop ax

and ax, 0f000h

jz is_80286

mov ax, 0

ret

is_80286:

mov ax, 1

ret

cpu_80286 endp

; ==================================

; cpu_80386

; ==================================

. 386

cpu_80386 proc

pushfd

pop eax

mov ecx, eax

xor eax, 40000h

push eax

popfd

pushfd

pop eax

xor eax, ecx

jz is_80386

mov ax, 0

ret

is_80386:

push ecx

popfd

mov ax, 1

ret

cpu_80386 endp

; ==================================

; cpu_80486

; ==================================

cpu_80486 proc

pushfd

pop eax

mov ecx, eax

xor eax, 200000h

push eax

popfd

pushfd

pop eax

xor eax, ecx

je is_80486

mov ax, 0

ret

is_80486:

mov ax, 1

ret

cpu_80486 endp

end


 

Данный файл был оттранслирован при помощи  следующего пакетного файла:

masm /Zi askcpu. asm,,,,

 

Главный файл программы:

// =====================================================

// Определение типа процессора

// =====================================================

#include < stdio. h>

#include < conio. h>

#include < stdlib. h>

#include < memory. h>

extern void GET_CPU_MODEL(void);

extern char VENDOR_ID_MSG[12];

extern char CPU_MODEL;

extern long CPU_SIGNATURE;

extern long FEATURES_ECX;

extern long FEATURES_EDX;

extern long FEATURES_EBX;

int main(void)

{        

char buf[128];

GET_CPU_MODEL();

printf(" CPU model: %d\n", (unsigned)CPU_MODEL);

if(CPU_MODEL > = 5)

{

memcpy(buf, VENDOR_ID_MSG, 12);

buf[12] = 0;

printf(" Vendor ID: %s\n\n", buf);

printf(" CPU Signature %08. 8X\n", CPU_SIGNATURE);

printf(" CPU Feature EDX %08. 8X\n\n", FEATURES_EDX);

printf(" CPU type: %d\n",

(CPU_SIGNATURE & 0x3000) > > 12);

printf(" CPU family: %d\n",

(CPU_SIGNATURE & 0xF00) > > 8);

printf(" CPU model: %d\n",

(CPU_SIGNATURE & 0xF0) > > 4);

printf(" CPU stepping: %d\n\n", CPU_SIGNATURE & 0xF);

if(FEATURES_EDX & 0x1)

printf(" FPU detected\n" );

if(FEATURES_EDX & 0x800000)

printf(" MMX supported\n" );

}

getch();

return 0;

}

Поделиться:





Воспользуйтесь поиском по сайту:



©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...