Int 1fH – указатель графических символов 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Int 1fH – указатель графических символов



(слайд №46)

 

Этот вектор (0:007c) указывает на таблицу, определяющую изображения старших 128 символов (коды ASCII 128-255). Ее использует ROM-BIOS, когда выводит на экран символы в графическом (с битовой разверткой) режиме.

При запуске системы этот указатель устанавливается на F000:0000, так что старшие 128 символов в графическом режиме выдаются как случайный "мусор". команда DOS 3.x "GrafTabl" может использоваться для загрузки таблицы старших 128 символов и соответствующей переустановки данного вектора.

Можно создать собственную RAM-резидентную таблицу, например, чтобы предоставить курсив для графики. Таблица состоит из 128 групп по 8 байт в группе. Каждый байт представляет 8 точек по горизонтали, причем первый байт отвечает верхней строке точек, составляющих изображение символа. Например, определение символа "Л" могло бы быть следующим:


 

г7+6+5+4+3+2+1+0 смещение_в_таблице + 0: ¦ $ $ $ $ $ $ ¦ = 01111110 = 7e hex = смещение_в_таблице + 1: ¦ $ $ $ $ ¦ = 00111100 = 3c hex ¦ смещение_в_таблице + 2: ¦ $ $ $ $ ¦ = 01101100 = 6c hex ¦ смещение_в_таблице + 3: ¦ $ $ $ $ ¦ = 01101100 = 6c hex ¦=> = смещение_в_таблице + 4: ¦ $ $ $ $ ¦ = 01101100 = 6c hex ¦ ¦ смещение_в_таблице + 5: ¦ $ $ $ $ ¦ = 01101100 = 6c hex ¦ ¦ смещение_в_таблице + 6: ¦$ $ $ $ $ ¦ = 11001110 = ce hex ¦ ¦ смещение_в_таблице + 7: ¦ ¦ = 00000000 = 00 hex =- ¦ +-+-+-+-+-+-+-+-+ ¦ +====================+ ¦ +===============¦=============+8-байтовая последовательность: 7еH,3cH,6cH,6cH,6cH,6cH,ceH,00H стояла бы в таблице по смещению, соответствующему символу "Л". Так как код ASCII буквы 'Л' равен 139, а таблица начинается для символа с кодом 128, это будет 12-я группа из 8 байт (смещение - 88 байт от начала таблицы).

 

Замечание:

Младшие 128 символов хранятся в ROM-таблице по адресу f000:fa6e. Это не указано в документации, но, похоже, этот адрес остается постоянным во всех IBM-версиях ROM. этот адрес жестко закодирован в кодах программы INT 10H, так что вы не можете использовать свою таблицу для младших 128 символов (если у вас не EGA, который позволяет переопределять весь набор символов).

 

Лекция №8.

 

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

(слайд №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. Этот бит был впервые определен в процессоре 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

(слайд №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 – слово, состоящее из отдельных флагов, характеризующих возможности процессора (feature flags). Регистры 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 Тип процессора
  Процессор, изготовленный производителем OEM
  Процессор OverDrive
  Процессор типа Dual, который можно использовать в двухпроцессорных системах
  Зарезервировано

 

(слайд №51)

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

 

Тип процессора Код семейства Код модели Описание процессора
      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

 


(слайд №52)

Биты, возвращаемых командой 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;

}

 



Поделиться:


Последнее изменение этой страницы: 2016-04-26; просмотров: 344; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.14.253.221 (0.137 с.)