Глава 20. Микропроцессоры 8086, 80186, 80286, 80386, 80486,МП 80286.

Основные регистры остались те же.

Рабочие регистры (80286)

АХ

ЛЬ

АН

вх

В1_

вн

сх

СЬ

сн

ПА

ПЬ

ПН

Аккумулятор

База

Счетчик

Данные

Регистры - указатели (80286)

15 О

SP Указатель (стека)

ВР Указатель базы

Индекс источника

DI Индекс получателя

Сегментные регистры (80286)

15 О

CS

Б8

ES

Сегмент кода

Сегмент данных

Сегмент стека

Дополнительный сегмент

Программный (80286)

1B О

IP

Был добавлен регистр, касающийся защищенного режима.

Слово-состояние машины

15 О

Значение битов:

0 (РЕ) - бит защищенного режима. Установка данного бита в 1 разрешает защиту на уровне сегментов.

1 (MP) - бит наличия сопроцессора. Управляет функцией команды ожидания. На­чиная с микропроцессора 80486 должен всегда быть равен 1.

2 (ЕМ) - бит отсутствия сопроцессора. Если бит установлен в 1, то выполнение любой команды сопроцессора или команды WAIT вызывает особый случай (7).

3 (TS) - признак, что задача была переключена. 4-15 - резерв.

Регистр глобальной дескрилторной таблицы 23 0

GDTR

Регистр дескрипторной таблицы прерываний 23 О

IDTR

Регистр локальной дескрипторной таблицы 15 О

LDTR

Регистр задач

15

TR

Регистр флагов 15 О

Добавилось (по сравнению с 8086) использование двух новых битов, касающихся работы в защищенном режиме.

12-13 (ЮPL) - уровень привилегий. 14 (ОТ) - вложенная задача.

МП 80386.

Большая часть регистров процессора стали 32-битными.

Рабочие регистры 31 15 0

ЕАХ

 

АХ = АН + А1

Аккумулятор

ЕВХ

 

ВХ = ВН + В1_

База

ЕСХ

 

СХ = СН + С1_

Счетчик

ЕРХ

 

ЭХ = РИ + 01.

Данные

Регистры указатели

31 . 15 0

ЕБР

 

вР

Указатель (стека)

ЕВР

 

ЭР

Указатель базы

Ев!

 

в!

Индекс источника

ЕР! "

 

Р!

Индекс получателя

Сегментныерегистры

1S

CS

DS

SS

ES

FS

GS

Сегмент кода Сегмент данных

Сегмент стека

Дополнительный сегмент

Добавилось два новых сегментных регистра.

31

Программный счетчик 15

IP

Структура дескриптора для процессора 80386 осталась той же (см. главу 5), но старшие 16 бит, бывшие в резерве, теперь используются. В частности, там хранится теперь старший байт базового 32-битного адреса сегмента.

Регистры ОБТЯ, ЬБТК, ГОТРч,ТБ1 имеют такие же размеры, каки у микропроцес­сора 80286.

31

Регистр флагов 15

FLAGS

Добавилось (по сравнению с 80286) использование двух новых битов.

16 - флаг итога - используется при отладке. Используется для временного запре­щения особых случаев отладки.

17 - флаг виртуального режима - включает виртуальный режим.

Другие регистры.

Региструправления 31 15 О

СРО

Младшие 16 бит регистра СЖ) называются словом состояния машины (см. микро­процессор 80286). Биты:

0 - РЕ - включение защищенного режима,

1 - МР - управление сопроцессором,

2 - ЕМ - эмуляция сопроцессора (бит отсутствия),

3 - Т8 - бит переключения задач.

31 - РО - включениеуправления страницами. Т.о. добавился один новый бит (31-й).

Регистр СЮ - зарезервирован.

Регистр СЮ. - содержит линейный адрес ошибки страницы. Регистр СЫЗ - базовый адрес каталога страниц (биты 12-31). Таким образом, добавились регистры СР1-СР3. Слово состояния машины пре­вратилось в регистр СРО.

Регистры отладки (32-битные).

БРО-БРЗ - четыре линейных точки останова. Формируемые программой адреса при выполнении каждой команды сравниваются с адресами данных регистров. При совпадении адресов генерируется сигнал особого случая отладки.

БР4-БР5 - зарезервировано.

БР6 - текущее состояние точек останова (текущее состояние отладки). БЫ7 - региструправления отладкой. Для каждой контрольной точки отводится поле (8 бит), позволяющее задать:

- регистрацию контрольной точки в одной или любой задаче;

- регистрацию контрольной точки при обращении к памяти для записи/счи­тывания данных или для выборки команды;

- фиксацию контрольной точки в зависимости от размера операнда, к которо­му производится обращение.

Еще регистры (32-битные).

TR6.TR7 - (тест - регистры) регистры для работы с буфером ассоциативной связи кэш-памяти для трансляции линейных адресов в физические.

МП 80486.

Не перечисляя регистры 486-го микропроцессора, укажу лишь отличия его в этом плане от 386-го микропроцессора.

Регистр флажков дополнился новым флагом АС - 18-й. Флажок контроля вырав­нивания.

Регистр CRO также дополнился новыми флажками.

4 - ЕТ - тип расширения. Поддержка команд математического сопроцессора.

5 - NE - бит численной ошибки. Бит разрешения стандартного механизма числен­ной ошибки.

6-WP- бит защиты от записи. Защищает от записи страницы уровня пользователя от обращения режима супервизора.

7 - AM - запрещает или разрешает контроль выравнивания.

8 -NW- бит несквозной записи. Запрещение сквозной записи (1) может привести к появлению в кэш-памяти устаревшихданных.

9 - CD - запрещение или разрешение внутренней кэш-памяти.

Регистр CR3.

Биты 12-31 - физический адрес каталога страниц.

Бит 2 - PWT - сквозная запись.

Бит 3 - PSD - запрещение кэширования страницы.

Кроме того, в состав микропроцессора 80486 фактически вошел арифметический сопроцессор, полностью совместимый с процессором 387.

МП PENTIUM.

В регистре флагов дополнительно использованы разряды 19-21. 21 - ID - флаг доступности команды идентификации (СРЕГО); 20 - VIP - виртуальный запрос прерывания; 19 - VIF - виртуальная версия флага IF для многозадачных систем.

Добавлен управляющий регистр CR4 с разрядами 0-6.

0-УМЕ-разрешениеиспользованиявиртуальногофлагапрерыванийврежимеУ86,

1 - РVI - разрешение использования виртуального флага прерываний в защищен­ном режиме,

2 - TSD - превращение инструкции RDTSC в привилегированную,

3 — DE - разрешение точек останова по обращению к портам ввода-вывода.

В регистре DR6 невозможно изменить значение разряда 12. Кроме того, в микро­процессоре Pentium увеличено количество так называемых тест-регистров. Их коли­чество достигает теперь

II. Команды реального режима. МП 8086/8088.

Команды данного микропроцессора описаны в Главе 4 и Приложении 1, и здесь мы не будем повторяться.

МП 80186/80188.

О командах данного микропроцессора см. также главу 5. BOUND REG,MEM - контроль попадания в диапазон.

В регистр помещается длина массива. В MEM находится нижнее значение индек­са, в МЕМ+2 - верхнее значение. Если длина массива выходит за указанный диапазон, то генерируется прерывание 5.

ENTER N,M - образование стекового кадра для процедуры.

ENTER16,3-peзepвиpyeтcяl6бaйтдлялoкaльныxпepeмeнныx.УpoвeньвлoжeннocтиЗ.

Данная команда используется в основном в трансляторов языков высокого уровня.

LEAVE - удаление стекового кадра процедуры. Работает в паре с командой ENTER.

INS - ввод циклический. 1NSB, INSW, INSD. Работает как строковая команда.

Оите-вьгеодциклический.ОиТ8В,ОиТ8\У,ОиТО.Работаеткакстроковаякоманда.

PUSHA, РОРА - поместить в стек и извлечь из него регистры DI, SI, BP, SP, ВХ, DX,CX,AX.

PUSHN, N - число.

Расширенакомандазнаковогоумножения.

Например, IMULDX,CX,123 (BX*123->DX)(cm. главу 5).

Расширена команда битового сдвига: SHLAX,N , где№> 1.

МП 80286.

Множество команд реального режима совпадает со множеством команд микро­процессора 80186.

МП 80386.

BSFREG.REG/MEM сканирование битавперед. Команда сканирует второй опе­ранд и заносит номер первого единичного бита в первый операнд. Если единички нет, то устанавливается бит Z.

BSR REG,REG/MEM сканирование бита назад. Аналогичная предыдущей.

ВТ REG,REG/MEM/N флажку CF передается битиз первого операнда за номером, определяемым вторым операндом.

инвертирует     в первом операнде, номер которого опре­деляется вторым операндом. Старый бит передается в CF.

сбрасывает      в первом операнде, номер которого опре­деляется вторым операндом. Старый бит передается в CF.

BTR REG,REG/MEM/N устанавливается бит в первом операнде, номер которого определяется вторым операндом. Старый бит передается в CF.

CWDE - преобразование слова в двойное слово.

CDQ - преобразование двойного слова в четвертное слово.

SHLDREG/MEM,MEM ,N (SHRDREG/MEM,MEM,N) сдвигдвойной (вправо, вле­во). Команда двойного сдвига перемещает набор бит первого операнда влево или вправо на число разрядов, определяемым третьим операндом. Освобождающиеся биты за­полняются из второго операнда.

SETCC - установка байтапо условию. Указанный байт операнда устанавливается в 1 в зависимости от условия. Условие аналогично условиям переходов.

Множество команд расширено по сравнению с командами микропроцессора 80286:

Во-первых, за счет использования в командах 32-битных регистров. Например, ADDEAX,234567H.

Во-вторых, за счет использования суффикса D. Например, CMPSD - сравнение строковых двойных строк, IRETD - возврат из прерывания в 32-битном режиме, MOVSD - пересылка строки из двойных слов и т.д.

МП 80486.

Новые команды: BSWAP,XADD, CMPXCHG.

BSWAP изменяет порядок байтв 32-битном регистровом операнде.

XADD MEM,REG - источник заменяется получателем, а получатель суммой ис­точника и получателя.

CMPXCHG MEM,AK,REG (АК- аккумулятор) - если значение операнда получа­теля и аккумулятора равны, операнд-получатель заменяется операндом-источником. В противном случае операнд-получатель загружается в аккумулятор.

МП PENTIUM.

Добавлены следующие команды:

CMPXCHG8B, CPUID, RDTSC, RDMSR WRMSR, RDTSC и стандартные коман­ды загрузки и выгрузки регистра CR4. Рассмотрим эти команды.

CMPXCHG8B REG/MEM,REG - сравнение и обмен восьмибайтовых величин. CPUID - получение информации о процессоре. RDMSR REG/MEM - чтение регистров (TR1-TR12). WRMSR REG/MEM - запись регистров (TR1-TR12). RDTSC - чтение счётчика тактов.

III. Команды защищенного режима.

8086/8088.

Команды защищенного режима отсутствуют.

МП 80186/80188.

Команды защищенного режима отсутствуют.

МП 80286.

Данные команды появились в процессоредля обслуживания защищенного режима.

ARPL - коррекция в селекторе уровня привилегий инициатора запроса.

LGDT - загружает GDT из памяти. При загрузке передается шесть.байт. Первые пять байт загружаются в регистр GDT, шестой байт игнорируется (загружается в 386-м процессоре). Используется при инициализации. LGDTMEM.

SGDT - передает содержимое регистра GDT в адресуемую область памяти. Ко­манда используется в системных отладчиках.

SGDTMEM.

- загружает операнд-слово из регистра или памяти в регистр LDT. Данное слово будет являться селектором, определяющим выбор локального дескриптора из таблицы GDT. Используется при инициализации. LLDTREG/MEM.

SLDT - передает содержимое регистра LDT в операнд-слово. Команда, обратная LLDT. SLDT REG/MEM.

LAR - команда загружает в свой первый операнд байт доступа дескриптора, выби­раемый вторым операндом. LARREG,REG/MEM

LSL - действует аналогично LAR, но загружает в свой первый операнд значение предела выбранного дескриптора.

LSL REGjREG/MEM.

LMSW - загружает из памяти или регистра регистр состояния. Используется для перехода в защищенный режим. Например, LMSWAX. SMSW- команда, обратная предьщущей.

LTR - загрузка регистра задачи. Выполняется раз после перехода в защищен­ный режим. LTR REG/MEM.

STR - сохранение регистра задачи. REG,MEM.

CLTS - сброс флага переключения задачи.

LIDT- загрузка регистра таблицы прерываний. LIDTMEM.

SIDT- сохранение регистра таблицы прерываний. SIDTMEM.

- проверка сегмента на чтение. VERR

VERW- проверка сегмента на запись. VERWREG/MEM.

МП 80386.

Команды для защищенного режима расширились за счет доступа к новым регист­рам (CR,TR,DR). Например, MOVCR0,EAX.

МП 80486.

Три описанных ниже команды фактически не являются командами защищенного режима. Точнее, их следует назвать системными.

INVD - очищает внутреннюю кэш-память и выдает специальный цикл шины, ко­торый показывает необходимость очистки и внешней кэш-памяти. Данные во внеш­ней кэш-памяти с отложенной записью уничтожаются.

ENVLPG - применяется для задания недостоверности одного элемента буфера TLB.

WBINVD - производится очистка внутренней кэш-памяти и формируется специ­альный цикл шины, показывающий внешней кэш-памяти выполнить обратную записьее содержимого в основную память. После этого формируется еще один специальный цикл шины, вызывающий очистку внешней кэш-памяти.

МП PENTIUM.

По-видимому, новых команддля защищенного режима не появилось.

IV. 32-битная адресация.

В микропроцессоре 80386 размеры рабочих регистров составляют 32 бита. Соот­ветственно наряду с адресацией типа DS:[BX] стала возможна запись DS:[EBX]. Со­ответственно размер сегмента уже не ограничивается 64 килобайтами. Ниже пред­ставлена программа, демонстрирующая возможность 32-битной адресации.

DATA SEGMENT TST    DB ?

DATA ENDS

STAC SEGMENT STACK

DW 50 DUP(?)

STAC ENDS

CODE   SEGMENT USE16

ASSUME CS:CODE,   DS:DATA, SS:STAC

BEGIN:

; обнулить   32-битные регистры

MOV   EAX, 0

MOV    ebx, 0 ;установить регистр  DS   на   сегмент DATA

MOV    AX,DATA

MOV DS,AX ;в ячейке TST  -   код буквы 'A'

MOV    DS:TST,'A'

PUSH DS

LEA BX,TST ; получить  физический   адрес   сегмента DATA

SHL   EAX, 4 ;физический адрес ячейки TST  в EBX

ADD    EBX,EAX

XOR    AX,AX /установить регистр  DS  на  начало памяти

MOV    DS, AX ;содержимое ячейки TST  в DL

MOV    DL, [ebx]

MOV    AH, 2

INT 21H

POP DS

;делаем то же самое, но стандартным (сегментным) ;способом

LEA BX,TST MOV   DL, [BX] INT 21Н MOV АН,4СН

INT 21H CODE ENDS

. END BEGIN

Рис. 20.1. Пример 32-битной адресации в реальном режиме. Примеры 32-битного программирования Вы найдете также в главе 25.

V. Страничная адресация.

Сегментная адресация, исповедуемая семейством микропроцессоров INTEL, ос­нована на следующих положениях:

1. Адрес ячейки памяти состоит из двух компонент: адрес сегмента и адрес в сег­менте (смещение).

2. Адрес сегмента содержится либо в сегментном регистре (реальный режим), либо в дескрипторе (защищенный режим), на который указывает содержимое соот­ветствующего сегментного регистра.

3. Сегмент и смещение однозначно определяют некоторую величину, называемую линейным адресом. Линейный адрес совпадает с физическим адресом. Физи­ческий же адрес ячейки — это просто ее порядковый номер.

В микропроцессоре 80386 появилась так называемая страничная адресация. Стра­ничная адресация работает только в защищенном режиме. Если страничная адресация включена (см. ниже), то линейный адрес, получившийся в результате преобразования сегментного адреса и смещения, подвергается дополнительному преобразованию. В результате линейный адрес может не совпадать с физическим адресом.

В страничном преобразовании базовым объектом является страница длиной 4 Кб. Поскольку линейное адресное пространство 386-го микропроцессора составляет 4 гига­байта, размер реально существующей памяти при этом, естественно, много меньше. Это адресное пространство разделяется на 1 М страниц. Причем реально существует только часть страниц. Несуществующие страницы, которые мы назовем виртуальными, могут храниться надиске и загружаться по мере необходимости. Посколькуразмер всех страниц одинаков, это значительно упрощает загрузку и выгрузку страниц. Эту работу, разумеется, выполняет операционная система. Прикладные программы при этом остаются в неведе­нии . В сегментной организации имеется 4уровня привилегий (см. Главу 5) - О, 1,2,3. В страничной организации есть только два уровня: уровень пользователя соответствует уров­ню 3, и уровень супервизора - соответствует уровням 0,1,2 сегментной организации.

В процессе страничного преобразования старшие 20 бит линейного 32-битного адреса заменяются другим значением - номером физической страницы. Младшие 12 бит остаются неизменными. Такое преобразование происходит в два этапа:

1. Старшие 10 бит линейного адреса (плюс 2 нуля справа) указывают на элемент (индексируют) в структуре, которая называется каталогом страниц. КаталЩгстра-ниц образуетсядля каждой задачи независимо. Его 20-битный физический ад­рес содержится в регистре СЯЗ (биты 12-31, остальные биты считаются нуле­выми). Каталогстраниц состоит из 32-битных элементов. Каждый элемент ука­зывает на одну из 1024таблиц страниц.

2. Средние биты 12-21 линейного адреса, дополненные двумя младшими нулями, индексируют, выбирая из нее один из элементов, который указываетуже на кон­кретную страницу. Каждая из таблиц страниц содержит З2-битные элементы (1024элементов).

3. В результате "сложения" индекса в каталоге страниц, индекса в таблице стра­ниц и 12-битногосмещения получается реальный (физический) адрес.

Элемент каталога страниц и таблицы страниц имеет идентичную структуру и пред­ставлен ниже.

Адрес таблицы или страницы

9-11

7-8

6

5

4

3.

2

1

0

Описание бит:

0 -1 - страница находится в памяти, 0 - надиске при обращении кстранице, кото­рой в памяти нет, генерируется специальное прерывание.

1 -1 - разрешено чтение-запись, 0 - только чтение.

2 - 0 - уровень супервизора, 1 - уровень пользователя. 3-4-битызапрещениякэшированиястраницисквознойзаписи. 5-1- идет обращение к странице для чтения или записи.

6 -1 - идет обращение к таблице. 7-8-равны 0.

9-12 - могут использоваться для нужд программистов.

Для уменьшения объема памяти, используемой таблицами страниц, операционная система учитывает реальный объем памяти и строит таблицы страниц, исходя из этого объема, а не из возможного адресного пространства. Причем уменьшается количество таблиц страниц, а не их размер.

Ниже приводится последовательность команд, разрешающихстраничную адресацию:

PUSHFD CLI

MOV  EAX,KAT_ADR   ; физический адрес каталога MOV CR3,EAX

MOV EAX,CRO /разрешить  страничную адресацию

ВТС ЕАХ,31 MOV CR0,EAX

JMP   NEXT ■

NEXT:

POPFD

Добавим также, что для микропроцессоров Pentium появилась возможность опе­рировать со страницами размером в А Мб.

На этом мы заканчиваем рассмотрение семейства процессоров INTEL. Остаток главы посвящен рассмотрению программирования с использованием арифметическо­го сопроцессора.

VI. Арифметический сопроцессор.

Один ум хорошо, а два - лучше.

Русская пословица.

Представленный ниже материал вполне достаточен для программирования ариф­метического сопроцессора. Для заинтересованных читателей укажу также книги, где можно получить исчерпывающие сведения: [2,17,32]. Надо иметь в виду, что, начиная с процессора 80486, сопроцессор стал встроенным. В этой связи значение его резко возросло. На современном компьютере Вы можете смело использовать его команды. В конце приложения дается полный список таких команд, а также другая справочная

информация о сопроцессоре.

Арифметический сопроцессор является вспомогательным процессором и не может работать самостоятельно, и не может осуществлять самостоятельно выборку команд. Команды его могут идти вперемежку с командами микропроцессора. Оба процессора подключены к системной шине. Выборку команд осуществляет микропроцессор, и все команды попадают в оба процессора, но каждый выполняет свои. Микропроцес­сор, однако, принимает некоторое участие в выполнении команд сопроцессора. Если в команде сопроцессора требуется вычислить физический адрес или необходимо счи­тать данные из памяти, то микропроцессор делает это, выставляя адрес или данные на шину, откуда их считывает сопроцессор. То есть связь между процессорами осуще­ствляется через шину.

Из сказанного становится ясно, что сопроцессор в силу своей несамостоятельно­сти синхронизирует свои действия с действиями микропроцессора, т.е. ждет, когда микропроцессор сделает выборку очередной команды. Однако необходима и обратная синхронизация. Необходимость эта возникает в двух случаях:

а) синхронизация по командам - передавать очередную команду сопроцессору можно, только если он готов к выполнению, т.е. выполнил последнюю команду;

б) синхронизация по данным - микропроцессор использует данные, которые исполь­зуются также сопроцессором, данные должны быть готовы. Такая связь осуще­ствляется по линии TEST. Активный сигнал на линии говорит о готовности со-процессора. Проверку этого сигнала осуществляет команда WAEP (см. главу 4).

Синхронизацию по командам помогает осуществлять ассемблер. Когда Вы, на­пример, в своей программе пишите команду FLDZ(cm. ниже), то ассемблер автомати­чески генерирует следующую последовательность: WAIT/FLDZ. Команды сопроцес­сора можно вводить и с помощью мнемоники ESC. Например, можно записать коман­ду FIDEV [SI] - разделить число, находящееся в вершине стека (см. ниже) на целое из ячейки памяти Щ.

После трансляции ассемблер, как уже было сказано сгенерирует две команды: WA1T/FIDIV [SI]. Если же мы запишем в программе директиву ESC 16H,[SPj,to будет сгенерирована всего одна команда FIDIV.

Программная модель арифметического сопроцессора имеет стековую основу - во­семь 80-битных регистра, взаимодействие между которыми носит стековый характер. Трехбитовый указатель стека ST (или ST(0)) направлен на регистр, являющийся в дан­ный момент вершиной. При операции включения в стек осуществляется декремент указателя, а в новую вершину стека помещаются загружаемые данные. При операции извлечения из стека в получатель из вершины извлекается данное, а затем осуществ­ляется инкремент указателя. Стек имеет кольцевую структуру. Поэтому если указа­тель был равен 000В и в стек положили данное, значение указателя станет 111в. В командах сопроцессора допускается явное или неявное обращение к вершинам стека. Так команды с одним операндом (унарные) предполагают некоторую операцию (вы­числение корня, синуса и т.д.) с содержимым регистра, находящегося в вершине. Ре­зультат команды при этом помещается в этот же регистр. В бинарных же операциях (два операнда) часто операндами являются два верхних элемента стека, а результат помещается на место одного из них. Возможна и прямая адресация к элементам стека: FADD ST,ST(2) - складывает содержимое верхнего регистра с регистром, отстоящим от него на 2 (например, R3 с R5), и результат помещается в вершину.56

С каждым регистром сопроцессора связано двухбитовое поле, называемое тэгом. Тэг фиксирует наличие в регистре действительного ненулевого числа - 00В, истинно­го нуля - 01В, специального числа - 10В, отсутствие данных Тэг используется сопроцессором, в частности, для фиксирования особых случаев (загрузка несуществу­ющего числа, запись в занятый регистр и т.д.).

Ниже представлена простая программа суммирования элементов целочисленного массива. Результат заносится в ячейку SUM. Для проверки результата мы выводим сим­вол, соответствующий этому числу. Т.к. результат должен быть равен 65, то и напечатана должна быть буква «А». Как уже отмечалось, перед командами сопроцессора автомати­чески ставится команда WAIT. Нам, однако, приходится использовать эту команду и от­дельно - перед выводом результата. Делается это для того, чтобы сопроцессор успел пере­дать данные в ячейку памяти. Данная программа является иллюстрацией работы сопро­цессора, адля выполнения действий с целыми числами более эффективен обычный мик­ропроцессор. Сопроцессор эффективен при работе с числами в вещественном формате.

CODE SEGMENT

ASSUME  CS : CODE, DS: CODE ORG 10OH

begin:

■    JMP  short BEG' ;массив для сложения

ARRAY DW 25,1,1,1,1,1,5,5,5,3,5,7,5

В основу вычисления арифметического сопроцессора положен так называемый принцип «обратной польской записи».

/сюда помещаем сумму

SUM      DW ?

BEG:

MOV СХ, 13 /инициализация сопроцессора

/предполагает,   в частности,   очистку всех регистров (тэг=11В) FINIT

/поместить в вершину стека О /здесь будет накапливаться сумма FLDZ ■

;с помощью регистра SI  будем адресовать массив XOR SI,SI

MORE :

/осуществить сложение,   а результат поместить  в  вершину стека FIADD DWORD  PTR ARRAY[SI] ADD    SI,2

LOOP MORE

/поместить результат в ячейку SUM

FIST  DWORD  PTR SUM /ждать сопроцессор

WAIT

/вывести результат  суммирования,    как символ MOV   АН, 2

MOV    DL, BYTE   PTR SUM

INT 21H RET

CODE ENDS

END BEGIN

Рис. 20.2. Пример использования сопроцессора.

Следующий пример написан на Си++. Это объясняется тем, что формат веще­ственных чисел довольно сложен. Пришлось бы писать процедуру преобразования из формата сопроцессора в ASCII-формат, что значительно бы усложнило програм­му. С другой стороны, формат вещественных чисел сопроцессора практически со­впадает с форматом вещественных чисел, которым оперирует Си. Кроме того, там есть хорошая функция PRINTF, позволяющая выводить на экран числа в различных форматах57.

Не попадитесь на удочку компилятора Си. Если трансляция проводится в режиме эмуля­ции сопроцессора, то команды сопроцессора будут заменены командами микропроцессо-ра8088/8086, апрограмма будетработать, как будто сопроцессор есть. Поэтомупосле отладки проверьте программу отладчиком.

#include <stdio.h>

void {

int

double sq;

/*далее  идет   ассемблерный код*/

asm {

/*   инициализация */

/*предполагает,   в  частности,   очистку  всех регистров (тэг=11В)*/ FINIT

/*поместить  в  вершину  стека О*/ /*здесь  будет  находиться число,   а потом его FLDZ

/*загрузить в вершину стека

FILD num /*извлечь корень*/

FSQRT

/*передать   в   ячейку  памяти*/ . FST sq

/*подождать сопроцессор*/

WAIT

}

/*вывести

printf("%f", sq) ;

};

Рис. 20.3. Пример использования сопроцессора.

Программа извлекает квадратный корень из целого числа 200. Практически вся

программа написана на ассемблере, а из языка Си используется лишь PRINTF. Про­грамму можно компилировать в любой модели, кроме TINY. Рассмотрим некоторые детали программы. Команда FILDNUM - загрузить из переменной NUM целое число в вершину стека сопроцессора. Указатель стека этом уменьшается на что в дан­ной задаче несущественно. Команда FST - передать содержимое вершины стека в вещественную переменную SQ. Указатель стека при этом не меняется. Команда FSQRT - извлечь корень из содержимого вершины стека и поместить же. Указатель стека не меняется. Команда WAIT перед PRINTF необходима, чтобы дождаться, когда ячей­ка SQ получит результат.

При использовании сопроцессора имейте в виду, что неумелое применение его команд может привести не к ускорению, а к замедлению работы программы. Такие действия, как сложение и вычитание над целыми числами, следует делать средствами обычного микропроцессора. Сопроцессор же нужно привлекать для операций деле­ния различных функций. Некоторое время назад, когда значительное количе­ство компьютеров шло без сопроцессора, использование его в программах было вообще нежелательно.

Ниже приводится программа проверки сопроцессора на вычисление экс­поненциальных функций. Программу следует откомпилировать в режиме ис­пользования сопроцессора. Чтобы облегчить понимание ^программы укажу, что у арифметического сопроцессора есть функция вычисления 2ЛХ - 1. Для того чтобы получить ЕХР(Х), нужно 2 возвести в степень, равную X, умно­женному на логарифм по основанию 2 от константы Е. Этот логарифм мо­жет загружаться в регистры сопроцессора специальной командой (см. про­грамму). ,

#include <stdio.h> Т-'* finclude <math.h>

double fun (double i)    /*вычисление экспоненты, значение 0<=i<=0.5*/

/♦проверка  работы сопроцессора*/ printf("%f\n",fun(0.35>) ; printf("%f\n",fun(0.4)) ; printf("%f\n",exp(0.35)) ; printf("%f\n",exp(0.4)) ;

Рис. 20.4. Справочные данные по арифметическому сопроцессору. Справочник команд арифметического сопроцессора 8087.

double ex;

asm { fintt

FLD i FLDL2E

fmul ST,ST(1) F2XM1 FST ех WAIT

};

ex+=l; return(ex)/

};

/*получаем ЕХР*/

/*инициализация */

/*загрузка числа*/

/*загрузка константы*/

/*находим произведение*/

/*вычисляем ЕХР(Х)-1*/

/*передать в ячейку*/

void main(void)

Арифметические команды.

Команда

Комментарий

Действия

FADDdst,src

Сложить вещественные числа

азК-о!з1)+(8гс)

FADDPdst,src

Сложить вещественные числа и извлечь из стека

иЖ-изО+^гс) 8Т<-(ЗТ)+1

FIADDsrc

Прибавить целое чис.

8Т(0)<-8Т(0)+(8гс)

FSUBdst,src

Вычесть вещественные числа

иж:-(ск)-(а-с)

FSUBPdst,src

Вычесть вещественные числа и извлечь из стека

с15г<-(с!51)-(5гс)    <- (8Т)+1

FSUBRdst,src

Обратное вычитание

 

FSUBRPdst,src

Обратное вычитание с извлечением из стека

иЖ-(8гс)-(и81)8Т<-(8Т)+1

FISUBsrc

Вычесть целое число

8Т(0)<-8Т(0)-(а-с)

FISUBRsrc

Обратное вычитание

ST(0)<-(src)-ST(0)

FMULdst,src

Умножить вещественные числа

&К-(а5Т.)*(5ГС)

FMULPdst,src

Умножить с извлечением из стека

ий<-(*1)*(8гс^Т<-^Т)+1

FIMULsrc

Умножить на целое число

ST(0)<-ST(0)*(src)

FDIVdst,src

Разделить вещественные числа

иа<-(ск)/(яс)

FDIVPdst,src

Разделить с извлечением из стека

<1й<-((Ь1У(8гс) ST <-(8Т)+1

FDIVRdst,src

Обратное деление

dst<-(src)/(dst)

FDIVRPdst,src

Обратное деление с извлечением из стека

&К-(8гс)/(<Ь1) ST <-(8Т)+1

FIDIVsrc

Разделить на целое число

ST(0)<-ST(0)/src

FIDPVRsrc

Обратное деление

8Т(0)<-8гс/8Т(0)

FABS

Абсолютноезначение

ST(0)<-|ST(0)|

FCHS

Сменить знак

ST(0)<-ST(0)

FPREM

Частичный остаток

ST(0)<-ST(0)MODST(1)

FRND1NT

Целая часть

целая

FSCALE

Масштабировать

8Т(0)<-8Т(0)Л8Т(1)

FSQRT

Извлечь корень

8Т(0)<-5ЯП(8Т(0))

FXTPACT

Выделить порядок и мантиссу

8Т(0)<-поряд.8Т(0) 8Т(1)<-мант.8Т(0)

Команды передачи данных

Команда

Комментарий

 

Действия

РШис

Загрузить вещественное число

8Т <- (БТ)-1 ЩО) <- (ею)

ИШнс

Загрузить целое число

БТ <-(8Т)-18Т(0)<-(8гс)

РВЬОбгс

Загрузить десятичное число

8Т<-(8Т)-18Т(0)<-(згс)

 

Запомнить вещественное число

<- ЯТ(0)

петая

Запомнить целое число

сіві <-8Т(0)

РВБТРс^

Запомнить десятичное число и извлечь из стека

(і5к-8Т(0)8Т<-(8Т)+1

РЗТРёй

Запомнить вещественное число и извлечь из стека

О8К-8Т(0)8Т<-(8Т)+1

РГЗТРсЫ

Запомнить целое число

и извлечь из стека

(Ій<-8Т(0)8Т<-(8Т)+1

РХОШ

Обмен

 

8Т(0)<->(ск)

Команды сравнения.

Команда

Комментарий

Действия

 

РСОМбгс

Сравнить вещественные числа

ст(0) - эгс Установить СЗ, СО

ИСОМР 8гс

Сравнить и извлечь из стека

ЩО) - еге 8Т<-8Т+1 Установить СЗ, СО

РСОМРР

Сравнить и дважды извлечь

эт(0) - ЯП) 8Т <- БТ+1 Установить СЗ, СО

РІСОМ 8гс

Сравнить с целым

ЭТ(0) - 8гс Установить СЗ, СО

РІСОМР 8гс

Сравнить с извлечением

ЩО) - эгсЗТ <- БТ+1 Установить СЗ, СО

ПЭТ

Проверить вершину стека

ЭТ(0) - 0.0 Установить СЗ, СО

РХАМ

Проанализировать вершину стека

Установить СЗ,С2,С1,СО

Трансцендентные функции.

Команда

Комментарий

Действия

Р2ХМ1

Вычислить 2Лх-1

8Т(0)<

:-2Л8Т(0)-1

БРАТАМ

Вычислить частичный арктангенс 2<-ак%(8Т(0)/8Т(1))

8Т<-ЭТ+1 8Т(0)<-г

РРТАЫ

Вычислить частичный тангенс       1§8Т(0)=У/Х ет(0)<-У8Г<-ЭТ-1

гТТ2Х

Вычислить У*1б

8Т(0)<

:-Х8Т<-8Т+1 БТ(0)<-7

РУЬ2ХР1

Вычислить У*1п

8Т<-8Т+1 8Т(0)<-г

Команды загрузки.

Команда

Комментарий

Действия

FLDZ

Загрузить нуль

ST<-ST-lST(0)<-0.0

FLD1

Загрузить 1

ST<-ST-1 ST(0)<-L0

FLDPI

ЗафузитьПи

ST<-ST-1ST(0)<-3.14..„

FLDL2E

.   Загрузить log

ST(0)<-log

FLDL2T

Загрузить log

ST(0)<-log

FLDLG2

Загрузить log

ST(0)<-log

FLDLN2

Загрузить log

ST(0)<-log

Команды управления сопроцессором.

Команда

Комментарий

Действия

FIN1T/FNIN1T

Инициализировать сопроцессор

Слово сос.<-03РЕ Слово тэгов<-ШЕЕ Всефлажки<-08Т<-0

FDISI/FNDISI

Запретить прерывания

1ЕМ<-1

FEN1/FNENI

Разрешить прерывания

1ЕМ<-0

FCLEX7FNCLEX

Сбросить флажки особых случаев

флажки<-0

FINCSTP

Инкремент указателя

8Т<-(8Т)+1

FDECSTP

Декремент указателя

ST<-(ST)-1

dst

Запомнить слово состояния

дз1<-словосос.

FSTCW/FNSTCWdst

Запомнить слово управления

упр.

FLDCWsrc

Загрузить слово управления

слово

FSTEN/FNSTEN dst

Запомнить среду

ёв^^ловоупр. а51+2<-словосос. аз1+4<-слово тэгов а51+6<-указ.команд азг-ь 10<-указ.операн.

FLDENVsrc

Загрузить среду

слово

СЛОВО СОС. <-8ГС+2 СЛОВО ТЭГ0В<-8ГС+4

указ.команд<-5гс+6 указ.операн.<-8гс+10

FFREEdst

Освободить регистр

^^1) - пустой

FNOP

Холостаякоманда

 

Запомнить полное состояние

сі5і<-слово упр.

азІ+2<-словосос. с1з1+4<-слово тэгов ск+6<-указ.команд dst+ 10<-указ.операн. аа+14..аа+84<-!5Т(0), 8Т(1),8Т(2)...

Инициализировать сопроцессор

РЮТОРчЕбгс

Восстановить полное состояние

слово

СЛОВО СОС<-8ГС+2

слово тэгов<-згс+4 указ.команд<-5гс+6 указ.операн. <-згс+10 8Т(О),$Т0)..<- <-5гс+ 14..5ГС+84

Программная модель арифметического сопроцессора.

Тэги

Р.3 Р.4 R5

Я7

Программная модель сопроцессора О 64

78 тд

Регистровый стек О 1

15

Регистр управления

Регистр состояния

Указатель команды

Указатель данных

Слово тэгов

Рис. 20.5. Программная модель арифметического сопроцессора.

Регистровый стек. Восемь 80-битных регистров, где числа хранятся во временном вещественном формате. Трехбитовое поле ST из регистра состояния определяет ре­гистр, являющийся вершиной стека. Стек имеет кольцевую структуру.

Двухбитовый тэг. Ассоциируется с каждым регистром стека. Совокупность тэгов образует слово тэгов. Значение тэгов:

00 - конечное не нулевое действительное число,

01-истинныйнуль,

10 - не число или бесконечность,

11 - регистр пуст.

Программист может интерпретировать содержимое регистров стека путем анали­за слова тэгов.

Слово управления.

Первые 6 бит составляют маску особых случаев. Если один из этих бит равен 1,то при возникновении соответствующего особого случая не возникает бит 0 - недействительная операция, бит 1 - случай денормализованного операнда, бит 2 - деление ненулевого значения на О, бит 3 - переполнение, бит4- антипереполнение, бит 5 - потеря точности.

Остальные биты:

бит 6 - резерв,

бит 7-1 - запретить прерывание центрального процессора, биты 8-9:

00-точность 24 бита,

10- 53 бита,

11- 64бита. биты 10-11:

00 - округление к ближайшему,

01 - округление вниз, 10-округление вверх, И-отбрасывание.

Бит 12 - интерпретация бесконечности:

0 - беззнаковая бесконечность,

1 - бесконечность со знаком.

Слово состояния. Является в некотором роде отражением регистра управления. Кроме того, здесь есть битыусловия: СО - 8-й бит, С1 - 9-й бит, С2 - 10-й бит, СЗ - 14-й бит. Вам не нужно анализировать условие. Биты условий вначале передаются в память, затем в регистр флажков микропроцессора. Далее используется обычная команда условного перехода.

Дальнейшее развитие сопроцессоров.

Здесь приводится краткий обзор развития сопроцессоров, начиная с 287-го и за­канчивая сопроцессором Pentium.

Сопроцессор 80287.

Основные отличия:

1. Может работать в реальном и защищенном режиме.

2. Команда WAIT, встроенная во все команды сопроцессора, поэтому применять ее отдельно не стоит.

3. Имеются отличия в слове состояния. Бит 6 устанавливается при некорректной работе со стеком. Бит 7устанавливается при возникновении немаскированного исключения.

4. Из управляющего слова удалены биты контроля над бесконечностью, а также бит 7.

5. Новые команды в сопроцессоре 287 отсутствуют. Дальнейшее развитие сопроцессоров.

Здесь приводятся те изменения, которые произошли с сопроцессором в дальней­шем, не конкретизируя, ккакому сопроцессору это относится (387-му, 487-муили...).

.1. Новые команды: FUCOMP st(i) - сравнение st(0) с st(0) без учета порядков и выталкивание из стека; FUCOMPP st(i) - сравнение st(0) с st(0) без учета порядков и двойное выталкивание из стека; FPREM1 - нахождение частичного остатка в стандар­те IEEE; FCOS - косинус st(0); FSIN - синус st(0); FSINCOS - синус и косинус (st(l)<-sin(st(0), st(0)<-cos(st(0)).