Робота в захищеному режимі мікропроцесора


МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ

НАЦІОНАЛЬНИЙ ТЕХНІЧНИЙ УНІВЕРСИТЕТ

”ХАРКІВСЬКИЙ ПОЛІТЕХНІЧНИЙ ІНСТИТУТ”

Розрахунково-графічне завдання №1

з курсу

"Мікропроцесорні системи"

Виконав:

ст. гр. xxxxxxx

xxxxxxxxxxxxx

Перевірив:

xxxxxxxxx

Харків 2006

Зміст

1. Індивідуальне завдання

2. Пояснення до змісту роботи

3. Опис програми

4. Текст програми

5. Результати роботи програми

6. Висновки

1. Індивідуальне завдання

Варіант 16

В захищеному режимі виконати наступні дії:

I. Викликати необхідне згідно із індивідуальним завданням виключення

II. Обробити задане виключення двома засобами:

а) прибравши причину виключення;

б) пропустивши команду, що визвала виключення.

III. Обробити задане зовнішнє переривання.

2. Пояснення до змісту роботи

Для виконання завдання необхідно виконати наступні дії:

розробити дескриптори усіх необхідних сегментів памяті і сформувати з них глобальну дескрипторну таблицю GDT.

за допомогою регістра GDTR задати базову адресу і розмір таблиці GDT;

розробити дескриптори усіх шлюзів, сформувати з них таблицю IDT.

за допомогою регістра IDTR задати базову адресу і розмір таблиці IDT;

сформувати дані для повернення в реальний режим;

заборонити масковані і немасковані переривання;

перевести мікропроцесор у захищений режим;

виконати в захищеному режимі дії, задані індивідуальним завданням;

повернутися в реальний режим;

дозволити масковані і немасковані переривання.

Для розуміння принципів програмування роботи в захищеному режимі необхідно розуміти його особливості. Захищений режим має такі особливості роботи з перериваннями (порівнюючи з реальним режимом):

1) вводиться новий тип переривань - виключення;

2) замість дальніх адрес в таблиці переривань використовуються дескриптори шлюзів;

3) таблиця переривань може знаходитися в будь-якому місці памяті.

Виключення поділяються на три типи:

- Помилка (trap);

- Пастка (fault);

- Аварія (abort).

Помилка - це виключення, що виникає в ситуації помилкових дій програми й припускається, що таку помилку можна виправити. Виконання програми продовжується починаючи із команди, при якій виникло виключення.

Пастка - це виключення, що виникає відразу після виконання команди. Виконання програми продовжується із наступної команди,що йде за командою на якій виникло виключення. На пастках строїться механізм відладки програм.

Аварія - це виключення, що не дозволяє продовжити виконання перерваної програми і сигналізує про серйозні порушення цілісності системи.

3. Опис програми

Для написання програми для виконання разрахункового завдання, скористались модулем PROT і програмою P_INT, що поставляються разом із індивідуальним завданням. В модулі PROT містяться основні необхідні константи і функції для створення власних таблиць GDT та IDT, для переходу в захищений режим, містяться також заглушки для всіх апаратних і програмних переривань. Програма P_INT містить перевизначення необхідних для роботи, або заданих за індивідуальним завданням переривань, в ній задається вміст таблиць GDT та IDT (в ній визначаються селектори заглушок, або необхідних переривань, на необхідних місцях), програма реалізує перехід в захищений режим, імітує виникнення програмного переривання, а також реалізує вічний цикл, до виникнення апаратного переривання. Після цього реалізується вихід до реального режиму, шляхом скидання мікропроцесору (не працює на нових моделях мікропроцесорів) або шляхом відновлення старої GDT та IDT, і повернення до реального режиму. Нами було додано необхідні по індивідуальному завданню апаратне і програмне переривання, і реалізовано виключну ситуацію для їх виникнення.

4. Текст програми

{----Модуль содержит константы, типы переменных, переменные,----}

{------процедуры и функции для работы в защищенном режиме-------}

unit prot;

interface

uses crt;

const

hex_tabl:array[0..15] of char=0123456789ABCDEF;

s2_string=Run time error: исключение ;

{--------------Селекторы дескрипторов сегментов---------------}

code_sel =$08; { кода программы, }

code_sel2 =$10; { кода модуля PROT, }

data_sel :word =$18; { данных, }

stack_sel :word =$20; { стека, }

video_sel :word =$28; { видеопамяти, }

mem_sel :word =$30; { расширенной памяти, }

{-----------------Биты байтов доступа сегментов---------------}

present =$80; { P=1 : сегмент есть в памяти }

nosys =$10; { S=1 : сегмент несистемный }

exe =$08; { E=1 : сегмент выполняемый }

down =$04; { ED=1: сегмент расширяется вниз }

wr_ena =$02; { W=1 : разрешена запись в сегмент }

rd_ena =$02; { R=1 : разрешено чтение из сегмента }

{---------Значения поля TYPE системных дескрипторов-----------}

type_int =$06; { шлюза прерывания для 80286 }

type_trap =$07; { шлюза исключения для 80286 }

type_TSS =$01; { сегмента TSS }

type_call =$04; { шлюза вызова }

type_task =$05; { шлюза задачи }

{-----------------Байт доступа сегмента кода------------------}

acc_code=present OR nosys OR exe OR rd_ena;

acc_code1=present OR nosys OR exe ;

{----------------Байт доступа сегмента данных-----------------}

acc_data=present OR nosys OR wr_ena;

{----------------Байт доступа сегмента стека -----------------}

acc_stack=present OR nosys OR wr_ena OR down;

{-----------------Байт доступа шлюза задачи-------------------}

acc_task =present OR type_task;

type

{-------------Структура дескриптора таблицы GDT---------------}

t_gdt=record

lim_l, { граница сегмента (биты 15-0) }

base_l :word; { базовый адрес сегм. (биты 15-0) }

base_h, { базовый адрес сегм. (биты 23-16) }

acc, { байт доступа }

lim_h, { G,D,0,X,граница сегм. (биты 19-16) }

base_hh:byte { базовый адрес сегм. (биты 31-24) }

end;

{-------------Структура дескриптора таблицы IDT---------------}

t_idt=record

off_l, { смещение (биты 15-0) }

sel :word; { селектор }

par, { число параметров }

acc :byte; { байт доступа }

off_h :word { смещение (биты 31-16) }

end;

{---------------Структура регистров GDTR и IDTR---------------}

t_dtr=record

lim :word; { граница и }

base :longint; { базовый адрес таблицы }

end;

{-----------------Структура TSS для МП 80286------------------}

t_tss_286=record

link, { селектор возврата }

sp0,ss0, { указатель стека кольца 0 }

sp1,ss1, { указатель стека кольца 1 }

sp2,ss2, { указатель стека кольца 2 }

ip,flags,ax,cx,dx,bx,sp,bp, { регистры }

si,di,es,cs,ss,ds,ldtr { микропроцессора }

:word;

end;

{--------------Структура TSS для МП 80386 и выше--------------}

t_tss_386=record

link, { селектор возврата }

esp0,ss0, { указатель стека кольца 0 }

esp1,ss1, { указатель стека кольца 1 }

esp2,ss2, { указатель стека кольца 2 }

cr3,eip,eflags,eax,ecx,edx,ebx, { регистры }

esp,ebp,esi,edi,es,cs,ss,ds,fs,gs,ldtr{ МП }

:longint;

bit_t, { бит ловушки задачи }

adr_BKVV:word; { смещение БКВВ }

Sys_inf, { поле для системной информации }

BKVV:longint; { БКВВ }

byte_end:byte; { байт завершения TSS }

end;

var

gdt:array[0..15] of t_gdt; { Таблица GDT }

idt:array[0..$32] of t_idt; { Таблица IDT }

gdtr, { Содержимое GDTR }

idtr, { Содержимое IDTR для работы в защищенном режиме }

idtr_r { Содержимое IDTR для работы в реальном режиме }

:t_dtr;

ofs_ret, { Смещение и }

sel_ret, { селектор точки возврата в реальный режим }

ofs_ret_mov, { Смещение метки ret_mov: }

cs_prot, { Селектор регистра CS в защищенном режиме }

cs1, { Значение сегмента кода модуля PROT }

{ Переменные для хранения значений регистров: }

real_ss, { SS, }

real_es, { ES и }

real_sp:word; { SP }

scan, { Скан-код нажатия клавиши }

cpu_type, { Номер типа микропроцессора }

res, { Признак сброса МП }

rm1, { Содержимое регистров маски 1-го }

rm2, { и 2-го контроллеров прерывания }

excep, { Номер исключения }

acc_int, { Байт доступа прерывания }

acc_trap, { Байт доступа ловушки }

t:byte; { Признак разрядности МП: T=0 - 16; T=8 - 32 }

function lin_adr(seg,off:word):longint;

function hex(p:longint):string;

function hw(p:word):string;

procedure init_gdt(i:byte;limit,base:longint;acces,

procedure init_idt(i:byte;p_off,p_sel:word;acces:byte);

procedure pic(mode:byte);

procedure init_gdtr;

procedure init_idtr_p;

procedure init_idtr_r;

procedure save_ret_real(seg,ofs:word;byte_shut:byte);

procedure not_int;

procedure en_int;

procedure set_unr(base,limit:longint;kseg,byte_6h:byte);

procedure save_sreg;

procedure reset;

procedure test_wr;

procedure init_tss_286 (var tss:t_tss_286; cs,ds,es,

ofs_task,ofs_task_stack,flags:word);

procedure init_tss_386 (var tss:t_tss_386; cs,ds,es,

ofs_task,ofs_task_stack,eflags:word);

procedure get_cpu_type(inf:byte;var cpu:byte);

procedure exc_00;

procedure exc_01;

procedure exc_02;

procedure exc_03;

procedure exc_04;

procedure exc_05;

procedure exc_06;

procedure exc_07;

procedure exc_08;

procedure exc_10;

procedure exc_11;

procedure exc_12;

procedure exc_13;

procedure exc_14;

procedure exc_16;

procedure exc_17;

procedure exc_18;

procedure PIC_1;

procedure PIC_2;

procedure keyb;

procedure int_30h;

procedure int_30hr;

procedure int_32h;

implementation

{------Преобразование логического адреса в линейный адрес-----}

function lin_adr;

begin

lin_adr:=longint(seg) shl 4+off

end;{lin_adr}

{-------------Преобразование данных в 16-ричную форму---------}

function hex(p:longint):string;

var s:string;

begin

s:=h;

repeat

s:=hex_tabl[p and $f]+s;

p:=p shr 4

until p=0;

hex:=s

end;{hex}

function hw(p:word):string;

var

i:byte;

s:string;

begin

s:=;

for i:=0 to 3 do begin

s:=hex_tabl[p and $f]+s;

p:=p shr 4

end;

hw:=s

end;{hw}

{------------Формирование дескриптора таблицы GDT-------------}

procedure init_gdt(i:byte;limit,base:longint;acces,

byte_6h:byte);

begin

with gdt[i] do begin

lim_l :=limit;

base_l :=base;

base_h :=base shr 16;

acc :=acces;

lim_h :=limit shr 16 or byte_6h;

base_hh:=base shr 24;

end

end; {init_gdt}

{------Формирование данных регистра GDTR и его загрузка-------}

procedure init_gdtr;

begin

gdtr.lim:=sizeof(gdt)-1;

gdtr.base:=lin_adr(seg(gdt),ofs(gdt));

asm

db 0fh,01h,16h { LGDT gdtr: }

dw gdtr { загрузка атрибутов GDT в GDTR из gdtr }

end

end; {init_gdtr}

{------------Формирование дескриптора таблицы IDT-------------}

procedure init_idt(i:byte;p_off,p_sel:word;acces:byte);

begin

with idt[i] do begin

off_l:=p_off;

sel:=p_sel;

par:=0;

acc:=acces;

off_h:=0

end

end; {init_idt}

{--------Сохрание и формирование данных регистра IDTR---------}

{--------и его загрузка для работы в защищенном режиме--------}

procedure init_idtr_p;

begin

asm

db 0fh,1,0eh { SIDT idtr: }

dw idtr_r { Сохранение атрибутов IDT в idtr_r }

end;

idtr.lim:=sizeof(idt)-1;

idtr.base:=lin_adr(seg(idt),ofs(idt));

asm

db 0fh,01h,1eh { LIDT idtr: }

dw idtr { Загрузка атрибутов IDT в IDTR из idtr }

end;

end;{init_idtr_p}

{------Формирование данных регистра IDTR и его загрузка-------}

{----------------для работы в реальном режиме-----------------}

procedure init_idtr_r;

begin

idtr_r.lim:=$3ff; { размер таблицы векторов, }

idtr_r.base:=0; { базовый адрес таблицы векторов }

end;{init_idtr_r}

{-------------Формирование данных для возврата----------------}

{-------------в реальлный режим после сброса МП---------------}

procedure save_ret_real;

begin

{-------------Сохранение значений регистров маски-------------}

{-------------1-го и 2-го контроллеров прерываний-------------}

rm1:=port[$21];

rm2:=port[$a1];

{---------Занесение в ячейки 40h:67h и 40h:69h адреса---------}

{------(смещение и сегмент) точки возврата в реальный режим---}

{-------------------после сброса МП---------------------------}

memw[$40:$67]:=ofs;

memw[$40:$69]:=seg;

{--------Занесение в ячейку КМОП памяти с адресом 0Fh---------}

{-----------байта состояния отключения (byte_shut).-----------}

{-------Значение Ah этого байта обеспечивает при сбросе МП----}

{---------переход по адресу в ячейках 40h:67h и 40h:69h;------}

{----код 5 помимо этого осуществляет также инициализацию------}

{----------------контроллеров прерываний----------------------}

port[$70]:=$0f;

port[$71]:=byte_shut;

end;{save_ret_real}

{----------------Запрет аппаратных прерываний-----------------}

procedure not_int;

begin

asm cli end; { маскируемых }

port[$70]:=$80; { и немаскируемых }

end; {not_int}

{---------------Разрешение аппаратных прерываний--------------}

procedure en_int;

begin

asm sti end; { маскируемых }

port[$70]:=$d; { и немаскируемых }

mem[$40:$17]:=0 { Сброс состояния клавиш-переключателей }

end; {en_int}

{------------------Установка режима "Unreal"------------------}

procedure set_unr(base,limit:longint;kseg,byte_6h:byte);

begin

{ Формирование таблицы GDT: }

init_gdt(0,0,0,0,0); { нуль-дескриптор }

init_gdt(1,limit,base,$92,$80); { дескриптор сегмента }

init_gdtr; { Создание данных и загрузка регистра GDTR }

not_int;{ Запрет маскируемых и немаскируемых прерываний }

asm { Переход в защищенный режим: }

db $0f,$20,0c0h { MOV EAX,CR0 }

db 66h,0dh { OR EAX,1 }

dd 1h

db $0f,22h,0c0h { MOV CR0,EAX }

{ Загрузка селектора заданного сегмента (kseg): }

mov ax,8

cmp kseg,0

jnz @3

db 8eh,0c0h { MOV ES,AX }

jmp @k

@3: cmp kseg,3

db 8eh,0d8h { MOV DS,AX }

jmp @k

@4: cmp kseg,4

jnz @5

db 8eh,0e0h { MOV FS,AX }

jmp @k

@5:db 8eh,0e8h { MOV GS,AX }

{ Возврат в реальный режим: }

@k:db 0fh,20h,0c0h { MOV EAX,CR0 }

db 66h,25h { AND EAX,FFFFFFFEh }

dd 0fffffffeh

db 0fh,22h,0c0h { MOV CR0,EAX }

end;

en_int

end;

{------------Программирование ведущего и ведомого-------------}

{-------------контроллеров прерываний для работы-------------}

{------в реальном (mode=0) и защищенном (mode=1) режимах------}

procedure pic(mode:byte);

var k1,k2:byte;

begin

if mode=0 then begin

k1:=8; k2:=$70

end else begin

k1:=$20; k2:=$28

end;

port[$20]:=$11; { 1-й ПКП: ICW1 }

port[$21]:=k1; { 1-й ПКП: ICW2 }

port[$21]:=4; { 1-й ПКП: ICW3 }

port[$21]:=1; { 1-й ПКП: ICW4 }

port[$a0]:=$11; { 2-й ПКП: ICW1 }

port[$a1]:=k2; { 2-й ПКП: ICW2 }

port[$a1]:=2; { 2-й ПКП: ICW3 }

port[$a1]:=1; { 2-й ПКП: ICW4 }

end;{pic}

{----------Сохранение значений сегментных регистров-----------}

procedure save_sreg;

begin

memw[0:4*$60]:=Dseg; { DS, }

real_ss:=Sseg; { SS и }

asm mov real_es,es end { ES }

end;{save_sreg}

{-------------Возврат в реальный режим по команде-------------}

{--------контроллера клавиатуры, выполняющей сброс МП---------}

procedure reset;assembler;

asm

mov res,1 { Установка признака сброса МП }

mov al,0feh { Команда сброса }

out 64h,al { микропроцессора }

@wait_res: { Ожидание во время сброса МП }

hlt

jmp @wait_res

db 0cbh { Межсегментный возврат }

end; {reset}

{---Проверка сохранения запрета записи в сегмент кода после---}

{------возврата МП из защищенного режима по команде MOV:------}

{-----если запрет сохранен - вырабатывается прерывание 13,----}

{-----обработчик которого (процедура reset) сбрасывает МП-----}

procedure test_wr;

begin

Meml[0:13*4]:=Longint(@reset); { Занесение адреса }

{ обработчика прерывания 13 - процедуры reset }

{ в область векторов }

asm

(* db 2eh { CS: }*)

mov ax,cs:[0]

(* db 2eh *)

mov cs:[0],ax { Запись в сегмент кода }

end;

pic(0); { Программирование ПКП для реального режима }

end; {test_wr}

{-----------------Формирование TSS для 80286------------------}

procedure init_tss_286 (var tss:t_tss_286; cs,ds,es,

ofs_task,ofs_task_stack,flags:word);

begin

tss.cs:=cs;

tss.ds:=ds;

tss.es:=es;

tss.ss:=ds;

tss.ip:=ofs_task;

tss.bp:=ofs_task_stack;

tss.sp:=ofs_task_stack;

tss.ldtr:=0;

tss.flags:=flags;

end;{init_tss_286}

{--------------Формирование TSS для 80386 и выше--------------}

procedure init_tss_386(var tss:t_tss_386; cs,ds,es,

ofs_task,ofs_task_stack,eflags:word);

begin

tss.cs:=cs;

tss.ds:=ds;

tss.es:=es;

tss.ss:=ds;

tss.eip:=ofs_task;

tss.ebp:=ofs_task_stack;

tss.esp:=ofs_task_stack;

tss.ldtr:=0;

tss.eflags:=eflags;

tss.bit_t:=0;

tss.adr_bkvv:=108;

tss.BKVV:=0;

tss.byte_end:=$ff

end;{init_tss_386}

{---------Определение типа микропроцессора (cpu_type)---------}

procedure get_cpu_type(inf:byte;var cpu:byte);

var

data_cach:array[1..4,1..4] of byte; { Данные о кэше МП }

max_inp, { Max значение вх. параметра команды CPUID }

EBX_, { Брэнд ID и др. }

feature, { Данные об особенностях МП (регiстр EDX) }

ECX_:longint; { Данные об особенностях МП (регiстр ECX) }

desc_L2:word; { Дескриптор кэша L2 }

{ Серийный номер микропроцессора: }

sn_1, { младшие 32 разряда, }

sn_2, { средние 32 разряда, }

sn_3:longint; { старшие 32 разряда }

vend:array[1..12] of char;{ Название фирмы-изготовителя }

brand_str:array[1..48] of char; { Брэнд-строка }

typ, { Тип МП (0-2) }

model, { Модель МП (4-6) }

i,j,

id_flag, { Флаг исполнения МП команды CPUID }

cpu_type, { Возвращаемый номер типа МП (0, 2-6) }

brand, { Брэнд ID }

CLFSH, { Длина строки кэша }

NMP, { Число логических процессоров в кристалле }

par:byte; { Число параметров команды CPUID }

unknown:boolean; { Признак нераспознавания типа МП }

s:string;

begin

unknown:=false;

id_flag:=0;

asm

pushf { Сохранить FLAGS }

@8086: { Проверка МП i8086: }

{ биты 12-15 регистра FLAGS всегда установлены }

pushf

pop ax

mov cx,ax

and ax,0fffh

push ax

popf

pushf

pop ax

and ax,0f000h

cmp ax,0f000h

mov cpu_type,0 { Микропроцессор: 8086 }

jne @80286

@80286: { Проверка МП i80286: }

{ биты 12-15 регистра FLAGS в реальном режиме всегда сброшены }

or cx,0f000h

push cx

popf

pushf

pop ax

and ax,0f000h

mov cpu_type,2 { Микропроцессор: 80286 }

jnz @80386

jmp @end_cpuid

@80386: { Проверка МП i80386: }

{ флаг AC (бит 18) регистра EFLAGS не может быть установлен }

db 66h { префикс разрядности: 32 разряда }

pushf

db 66h

pop ax { Занести в EAX исходное значение EFLAGS }

db 66h

mov cx,ax { Сохранить исходное значение EFLAGS в ECX }

db 66h,35h { Изменить командой XOR бит AC в EFLAGS }

dd 040000h

db 66h

push ax { Сохранить новое значение EFLAGS в стеке }

db 66h

popf { Заменить текущее значение EFLAGS }

db 66h

pushf

db 66h

pop ax { Запомнить новое значение EFLAGS в EAX }

db 66h

xor ax,cx

mov cpu_type,3

jz @end_cpuid { Если бит AC не меняется: }

db 66h { микропроцессор: 80386 }

push cx

db 66h

popf { Восстановить AC бит в EFLAGS }

@80486: { Проверка МП i486 и последующих моделей: }

{ установка/сброс ID флага (бит 21) в EFLAGS }

{ указывает на выполнимость команды CPUID на данном МП }

mov cpu_type,4 { Микропроцессор: i486 }

db 66h

mov ax,cx { Получить исходное значение EFLAGS }

db 66h,35h { Изменить командой XOR бит ID в EFLAGS }

dd 200000h

db 66h

push ax { Сохранить новое значение в стеке }

db 66h

popf { Занести новое значение в EFLAGS }

db 66h

pushf { Записать его в стек }

db 66h

pop ax { Переписать в EAX }

popf { Восстановить EFLAGS }

db 66h

xor ax,cx { Если бит ID не меняется: }

je @end_cpuid { МП не поддерживает команду CPUID }

{ Выполнение команды CPUID для определения }

{ фирмы, семейства, модели микропроцессора }

mov id_flag,1 { Установка флага }

{ выполнения МП команды CPUID }

db 66h

xor ax,ax { Параметр для CPUID: EAX=0 }

db 0fh,0a2h { Команда CPUID }

db 66h

mov ss:[bp+offset vend],bx { Из регистров EBX, }

db 66h { EDX }

mov ss:[bp+offset vend+4],dx { и ECX }

db 66h { в переменную vend }

mov ss:[bp+offset vend+8],cx { заносится имя фирмы }

cmp al,1 { В AL - наибольшее значение параметра CPUID }

jl @end_cpuid

mov par,al

db 66h

xor ax,ax

db 66h

inc ax { Установка параметра CPUID =1 }

db 0fh,0a2h { Команда CPUID: в AL - сигнатура МП }

db 66h { В sn_3 - старшие 32 разряда }

mov word ptr sn_3,ax { серийного номера МП }

mov word ptr EBX_,bx { В EBX_- Brand ID и др. }

db 66h

mov word ptr ECX_,cx { В EСX_- особенности МП }

db 66h

mov word ptr feature,dx { В EDX_- особенности МП }

mov cx,ax

and ax,0f0h

db 0c1h,0e8h,4 { Сдвиг в AX на 4 разряда вправо }

mov model, al { В AL - модель МП }

mov ax,cx

and ax,0f00h

db 0c1h,0e8h,8 { Сдвиг в AX на 8 разрядов вправо }

mov cpu_type, al { В AL - номер семейства МП }

mov ax,cx

and ax,3000h

db 0c1h,0e8h,12 { Сдвиг в AX на 12 разрядов вправо }

mov typ, al { В AL - номер типа МП }

db 66h

mov word ptr feature,dx { В feature - особенности МП }

cmp par,1

jz @end_cpuid

db 66h,0b8h { MOV EAX,2: установка параметра }

dd 2 { команды CPUID =2 }

db 0fh,0a2h { Команда CPUID }

db 66h

mov ss:[bp+offset data_cach],ax { В регистрах EAX, }

db 66h { EBX, ECX }

mov ss:[bp+offset data_cach+4],bx { и EDX - }

db 66h { информация о }

mov ss:[bp+offset data_cach+8],cx { кэш-памяти МП, }

db 66h { которая заносится в массив }

mov ss:[bp+offset data_cach+12],dx { data_cach }

@end_cpuid:

end;

s:=;

clrscr;

if id_flag=0 then begin { Определение типа МП }

case cpu_type of { без использования команды CPUID }

0:s:=i8086;

2:s:=i80286;

3:s:=i80386;

4:s:=i486;

end;

writeln(s);

end else begin

brand:=EBX_; { Значение брэнд ID }

for i:=1 to 4 do { Определение дескриптора }

for j:=1 to 4 do { кэша второго уровня }

if data_cach[i,4] and 128=0 then

if (data_cach[i,j]=$41) or

(data_cach[i,j]=$42) or

(data_cach[i,j]=$43) or

(data_cach[i,j]=$44) or

(data_cach[i,j]=$45) then begin

desc_L2:=data_cach[i,j];

break

end;

case cpu_type of

4:case model of

0,1:s:=i486 DX;

2:s:=i486 SX;

3:s:=iDX2;

4:s:=i486 SL;

5:s:=iSX2;

7:s:=iDX2 WB;

8:if typ=0 then s:=iiDX4

else s:=iDX4 OverDrive;

9:s:=AMD DX4;

14:s:=Am5x86 в режиме WT;

15:s:=Am5x86 в режиме WB;

else unknown:=true

end;

5: if vend=GenuineIntel then

case model of

1:if typ=0 then s:=Pentium (60,66)

else s:=Pentium OverDrive (60,66);

2:if typ=0 then

s:=Pentium (75..200)

else s:=Pentium OverDrive (75..133);

3:s:=Pentium OverDrive для 486;

4:if typ=0 then s:=Pentium MMX (166,200)

else s:=Pentium MMX OverDrive (75..133);

end else if vend=AuthenticAMD then

case model of

0:s:=AMD-K-PR75,90,100;

1:s:=AMD-K-PR120,133;

2:s:=AMD-K-PR120,166;

end;

6: case model of

1:s:=Pentium Pro;

3:if typ=0 then s:=Pentium II модель 3

else s:=Pentium II OverDrive;

5:case desc_L2 of

$41:s:=Celeron модель 5;

$43:s:=Pentium II модель 5;

$44:s:=Pentium II Xeon модель 5;

end;

6:s:=Celeron модель 6;

7:case desc_L2 of

$43: s:=Pentium III модель 7;

$44,$45:s:=Pentium III Xeon модель 7;

end;

8:case brand of

1:s:=Celeron модель 8;

2:s:=Pentium III модель 8;

3: if sn_3=$6B1 then s:=Celeron модель 8

else s:=Pentium III Xeon модель 8;

4: s:=Pentium III модель 8;

6: s:=Мобильный Pentium III-M модель 8;

7: s:=Мобильный Celeron модель 8;

end;

$A:s:=Pentium III Xeon модель A;

$B:s:=Pentium III Xeon модель B;

else unknown:=true

end;

$F:case model of

0: begin

s:=0.18-микронный ;

case brand of

8: s:=s+Pentium 4;

9: s:=s+Pentium 4;

$B: s:=s+Xeon;

end;

end;

1: begin

s:=0.18-микронный ;

case brand of

8: s :=s+Pentium 4;

9: s:=s+Pentium 4;

$A: s:=s+Celeron;

$B: if sn_3<$F13 then s:=s+Xeon MP

else s:=s+Xeon;

$C: s:=s+Xeon MP;

$E: s:=s+Xeon;

end;

end;

2: begin

s:=0.13-микронный ;

case brand of

8: s:=s+Pentium 4;

9: s:=s+Pentium 4;

$A: s:=s+Celeron;

$B: if sn_3<$F13 then s:=s+Xeon MP

else s:=s+Xeon;

$C: s:=s+Xeon MP;

$E: if sn_3<$F13 then s:=s+Xeon

else s:=s+мобильный Pentium 4-M;

$F: s:=s+мобильный Celeron;

end

end

end {else unknown:=true}

end;

for i:=1 to 12 do write(vend[i]);

if not unknown then writeln( ,s)

else writeln(МП сiмейства - ,cpu_type, модель - ,model);

asm

db 66h,0b8h

dd 80000000h { MOV EAX,80000000h }

db 0fh,0a2h { CPUID }

db 66h

mov word ptr max_inp,ax

end;

if max_inp>$80000000 then begin

asm

db 66h,0b8h { MOV EAX,80000002h }

dd 80000002h

db 0fh,0a2h { CPUID }

db 66h

mov ss:[bp+offset brand_str],ax { Из pегистpов EAX, }

db 66h

mov ss:[bp+offset brand_str+4],bx { EBX, }

db 66h

mov ss:[bp+offset brand_str+8],cx { ECX }

db 66h

mov ss:[bp+offset brand_str+12],dx { и EDX }

{в переменную brand_str заносятся первые 12 символов бренд-строки}

db 66h,0b8h

dd 80000003h { MOV EAX,80000003h }

db 0fh,0a2h { CPUID }

db 66h

mov ss:[bp+offset brand_str+16],ax

db 66h

mov ss:[bp+offset brand_str+20],bx

db 66h

mov ss:[bp+offset brand_str+24],cx

db 66h

mov ss:[bp+offset brand_str+28],dx

db 66h,0b8h { MOV EAX,80000004h }

dd 80000004h

db 0fh,0a2h { CPUID }

db 66h

mov ss:[bp+offset brand_str+32],ax

db 66h

mov ss:[bp+offset brand_str+36],bx

db 66h

mov ss:[bp+offset brand_str+40],cx

db 66h

mov ss:[bp+offset brand_str+44],dx

end;

for i:=1 to 48 do write(brand_str[i]);

writeln;

end;

if inf<>0 then begin

writeln(Особенности микропроцессора:);

for i:=0 to 21 do

if not ((i=10) or (i=20) or (i=28)) then begin

s:=;

case i of

0:begin

if (feature shr i) and 1=0 then s:=не ;

s:=s+содержит FPU;

end;

1:begin

if (feature shr i) and 1=0 then s:=не ;

s:=поддерживает расширения для режима ;

s:=s+виртуального 8086;

end;

2:begin

if (feature shr i) and 1=0 then s:=не ;

s:=s+поддерживает рассширенную отладку и CR4.DE;

end;

3:begin

if (feature shr i) and 1=0 then s:=не ;

s:=s+поддерживает страницы 4 МБ;

end;

4:begin

if (feature shr i) and 1=0 then s:=не ;

s:=s+поддерживает команду RDTSC и CR4.TSD;

end;

5:begin

if (feature shr i) and 1=0 then s:=не ;

s:=s+поддерживает команды RDMSR и WRMSR;

end;

6:begin

if (feature shr i) and 1=0 then s:=не ;

s:=поддерживает расширение физического адреса;

s:=s+ и CR4.PAE;

end;

7:begin

if (feature shr i) and 1=0 then s:=не ;

s:=s+поддерживает исключение 18 (MCE) и CR4.MCE;

end;

8:begin

if (feature shr i) and 1=0 then s:=не ;

s:=s+поддерживает команду CMPXCHG8B;

end;

9:begin

if (feature shr i) and 1=0 then s:=не ;

s:=s+содержит APIC;

end;

11:begin

if (feature shr i) and 1=0 then s:=не ;

s:=s+поддерживает команды SYSENTER и SYSEXIT;

end;

12:begin

if (feature shr i) and 1=0 then s:=не ;

s:=s+поддерживает регистры MTRR;

end;

13:begin

if (feature shr i) and 1=0 then s:=не ;

s:=s+поддерживает глобальные страницы и CR4.PGE;

end;

14:begin

if (feature shr i) and 1=0 then s:=не ;

s:=s+поддерживает MCA и регистр MCG_CAP;

end;

15:begin

if (feature shr i) and 1=0 then s:=не ;

s:=s+поддерживает команды CMOV, FCMOV и FCOMI;

end;

16:begin

if (feature shr i) and 1=0 then s:=не ;

s:=s+поддерживает таблицу атрибутов страниц PAT;

end;

17:begin

if (feature shr i) and 1=0 then s:=не ;

s:=s+ поддерживает 4 Мб страницы и адреса более 4 Гб;

end;

18:begin

if (feature shr i) and 1=0 then s:=не ;

s:=s+поддерживает 96-разрядный серийный номер МП;

end;

19:begin

if (feature shr i) and 1=0 then s:=не ;

s:=s+поддерживает команду CLFLUSH;

end;

21:begin

if (feature shr i) and 1=0 then s:=не ;

s:=s+поддерживает запись истории переходов;

end;

end;

writeln( ,s);

end;

readkey;

clrscr;

writeln(Особенности микропроцессора:);

for i:=22 to 31 do

if i<>30 then begin

s:=;

case i of

22:begin

if (feature shr i) and 1=0 then s:=не ;

s:=s+поддерживает программный контроль частоты МП;

end;

23:begin

if (feature shr i) and 1=0 then s:=не ;

s:=s+поддерживает MMX команды;

end;

24:begin

if (feature shr i) and 1=0 then s:=не ;

s:=s+поддерживает команды FXSAVE и FXRSTOR;

end;

25:begin

if (feature shr i) and 1=0 then s:=не ;

s:=s+поддерживает команды SSE;

end;

26:begin

if (feature shr i) and 1=0 then s:=не ;

s:=s+поддерживает команды SSE2;

end;

27:begin

if (feature shr i) and 1=0 then s:=не ;

s:=s+поддерживает разрешение конфликтов памятi;

end;

28:begin

if (feature shr i) and 1=0 then s:=не ;

s:=s+ поддерживает логические процессоры и HT;

end;

29:begin

if (feature shr i) and 1=0 then s:=не ;

s:=s+поддерживает температурный мониторинг;

end;

31:begin

if (feature shr i) and 1=0 then s:=не ;

s:=s+пiдтримує переривання по FERR;

end;

end;

writeln( ,s);

end;

readkey; clrscr;

if par>1 then begin

writeln(Число повторений команды CPUID с EAX=2 - ,

data_cach[1,1]);

writeln(МП имеет следующие блоки кэш-памяти:);

writeln;

for i:=1 to 4 do

for j:=1 to 4 do

if (i<>1) or (j<>1) then

if data_cach[i,4] and 128=0 then begin

s:=;

if data_cach[i,j]<>0 then begin

case data_cach[i,j] of

1:s:=TLB команд: 4 Кб страницы, 4-напр., 32 входа;

2:s:=TLB команд: 4 Мб стран., полностью ассоц., 2 входа;

3:s:=TLB данных: 4 Кб страницы, 4-напр., 64 входа;

4:s:=TLB данных: 4 Мб страницы, 4-напр., 8 входов;

6:s:=Кэш команд: 8 Кб, 4-напр., строка 32 байта;

8:s:=Кэш команд: 16 Кб, 4-напр., строка 32 байта;

$A:s:=Кэш данных: 8 Кб, 2-напр., строка 32 байта;

$C:s:=Кэш данных: 16 Кб, 4-напр., строка 32 байта;

$22:s:= Объедин. кэш L3: 512 Кб, 4-напр., строка 64 байта;

$23:s:= Объедин. кэш L3: 1 Мб, 8-напр., строка 64 байта;

$25:s:= Объедин. кэш L3: 2 Мб, 8-напр., строка 64 байта;

$29:s:= Объедин. кэш L3: 4 Мб, 8-напр., строка 64 байта;

$39:s:=Объедин. кэш L2: 128 Кб, 4-напр., строка 64 байта;

$3B:s:=Объедин. кэш L2: 128 Кб, 2-напр., строка 64 байта;

$3C:s:=Объедин. кэш L2: 256 Кб, 4-напр., строка 64 байта;

$40:if cpu_type=6 then s:=Кэш L2: не содержится

else if cpu_type=$f then s:=Кэш L3: не содержится;

$40:s:=Нет кэша L2 (семейство P6) или L3 (Pentium 4);

$41:s:=Объедин. кэш: 128 Кб, 4-напр., строка 32 байта;

$42:s:=Объедин. кэш: 256 Кб, 4-напр., строка 32 байта;

$43:s:=Объедин. кэш: 512 Кб, 4-напр., строка 32 байта;

$44:s:=Объедин. кэш: 1 Мб, 4-напр., строка 32 байта;

$45:s:=Объедин. кэш: 2 Мб, 4-напр., строка 32 байта;

$50:begin

s:=TLB команд: 4 Кб,2 Мб или 4 Мб страницы,;

s:=s+полностью ассоц., 64 входа;

end;

$51:begin

s:=TLB команд: 4 Кб, 2 Мб або 4 Мб страницы,;

s:=s+полностью ассоц., 128 входов;

end;

$52:begin

s:=TLB команд: 4 Кб, 2 Мб або 4 Мб страницы,;

s:=s+полностью ассоц., 256 входов;

end;

$5b:begin

s:=TLB данных: 4 Кб или 4 Мб страницы.,;

s:=s+полностью ассоц., 64 входа;

end;

$5C:begin

s:=TLB команд: 4 Кб або 4 Мб страницы.,;

s:=s+полностью ассоц., 128 входов;

end;

$5D:begin

s:=TLB команд: 4 Кб або 4 Мб страницы.,;

s:=s+полностью ассоц., 256 входов;

end;

$66:s:=Кэш данных секторный:8 Кб, 4-напр., строка 64 байта;

$67:s:=Кэш данных секторный: 16 Кб, 4-напр., строка 64 байти;

$68:s:=Кэш данных секторный: 32 Кб, 4-напр., строка 64 байти;

$70:s:=Кэш трас команд: 12 К микроинструкций, 4-напр.;

$71:s:=Кэш трас команд: 16 К микроинструкций, 8-напр. ;

$72:s:=Кэш трас команд: 32 К микроинструкций, 8-напр. ;

$79:begin



Не сдавайте скачанную работу преподавателю!
Данную курсовую работу Вы можете использовать как базу для самостоятельного написания выпускного проекта.

Другие популярные курсовые работы