Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Theme_Lab_Rab№2.doc
Скачиваний:
49
Добавлен:
23.03.2016
Размер:
1.11 Mб
Скачать

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

(слайд №47)

Для варианта №9, Лабораторной работы №2 – Определить тип центрального процессора.

Существует определенная методика определения типа центрального процессора.

Модели Intel 8086/8088

Способ распознавания таких процессоров основан на том факте, что биты12-15регистраFLAGSвсегда установлены в единицу.

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

pushf

pop ax

Первоначальное содержимое регистра FLAGSсохраняется в регистреCX:

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

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

(слайд №48)

Модель Intel 80386

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

В процессе проверки программа вначале получает исходное содержимое регистра 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не изменил своего значения, мы имеем дело с процессоромIntel80386.

Модель Intel 80486

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

Фрагмент кода, который нужно использовать для обнаружения процессора Intel80486, аналогичен фрагменту для процессораIntel80386. Отличие заключается в том, что вместобита 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

(слайд №49)

В новых процессорах фирмы 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– слово, состоящее из отдельных флагов, характеризующих возможности процессора (featureflags). РегистрыEBXиECXзарезервированы для моделей процессоров, которые будут разработаны в будущем.

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

_cpu_signature dd 0

_features_edx dd 0

. . .

mov _cpu_signature, eax

mov _features_edx, edx

(слайд №50)

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

Биты

Описание

0-3

Код модификации модели (stepping)

4-7

Код модели

8-11

Код семейства моделей

12-13

Тип процессора

14-31

Зарезервировано

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

Значение

битов 12 и 13

Тип процессора

00

Процессор, изготовленный производителем OEM

01

Процессор OverDrive

10

Процессор типа Dual, который можно использовать в двухпроцессорных системах

11

Зарезервировано

(слайд №51)

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

Тип процессора

Код семейства

Код модели

Описание процессора

00

0100

0100

Intel 486 SL

00

0100

0111

Intel DX2

00

0100

1000

Intel DX4

00, 01

0100

1000

Intel DX4 OverDrive

00

0101

0001

Pentium 60, 66;

Pentium OverDrive для процессоров Pentium 60, 66

00

0101

0010

Pentium 75, 90, 100, 120, 133, 150, 166, 200

01

0101

0010

Pentium OverDrive для процессоров Pentium 75, 90, 100, 120, 133

01

0101

0011

PentiumOverDriveдля систем на базе процессораIntel486

00

0101

0100

Pentium 166, 200 с командамиMMX

01

0101

0100

Зарезервировано. Будет использоваться процессорами PentiumOverDriveдля процессоровPentium75, 90, 100, 120, 133

00

0110

0001

Pentium Pro

00

0110

0011

Pentium II

00

0110

0101

Зарезервировано для новых процессоров P6

01

0110

0011

Зарезервировано для процессоров PentiumOverDriveдля процессоровPentiumPro

(слайд №52)

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

Бит

Описание

0

На кристалле процессора имеется арифметический сопроцессор, совместимый по командам с сопроцессором Intel387

1

Процессор может работать в режиме виртуального процессора 8086

2

Процессор может работать с прерываниями ввода/вывода, а также с битом DEрегистраCR4

3

Возможно использование страниц памяти размером 4 Мбайт

4

В процессоре есть команда RDTSC, которая может работать с битомTSDрегистраCR4

5

Набор регистров процессора, специфический для модели, доступен с помощью команд RDMSR,WRMSR

6

Возможна физическая адресация памяти с использованием шины с шириной, большей чем 32 разряда

7

В процессоре реализовано исключение MachineCheck(исключение с номером 18). Возможно использование битаMCE регистраCR4

8

В процессоре реализована команда сравнения и обмена 8 байт данных CMPXCHG8

9

В процессоре есть локальный APIC

10

Зарезервировано

11

В процессоре реализованы команды быстрого вызова системы SYSENTERиSYSEXIT

12

В процессоре есть регистры MemoryTypeRange

13

Доступен глобальный бит в PDEиPTE, а также битPGEв регистреCR4

14

Применена архитектура Machine Check Architecture

15

В процессоре реализованы команды условного перемещения данных CMOVCCи (при установленном бите 0)FCMOVCCиFCOMI

16-22

Зарезервировано

23

Применена технология 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;

}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]