- •Определение конфигурации компьютера программными средствами.
- •Лекция №6. Функции bios.
- •00HЗадание видеорежима
- •0Fh Чтение текущего состояния дисплея
- •Выбор режима работы - функция 00h
- •Определение типа центрального процессора
- •Функции прерывания dos int 21h
- •2А Получение даты (cx-год,dh-месяц,dl-день).
- •2С Получение времени (ch-час,cl-мин,dh-с,dl-1/100с).
- •2F Получение адреса dta в регистровой паре es:bx.
- •38 Получение государственно зависимых форматов.
- •Прерывание для обслуживания мыши
- •Часы реального времени
Определение типа центрального процессора
(слайд №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;
}