Команды пересылки данных

      В группе команд пересылки данных сопроцессора 8087 имеется

    всего три основных команды.  Команда загрузки помещает данные в

    регистровый стек 8087.  Обычно эти данные читаются из памяти

    системы, но команда загрузки может также извлечь число из самого

    стека и заменить им вершину стека.    Команда записи берет данные из

    вершины стека и помещает их в память ЭВМ.  Команда замены

    обменивает два числа в регистровом стеке сопроцессора 8087.

      На Фиг. 7.10 показан листинг ассемблера команд пересылки

    данных.  В текст в самом начале помещен набор макрокоманд

    процессора 8087 с помощью фрагмента:

 

      IF1

      INCLUDE  87MAC.LIB

      ENDIF

 

      Эта последовательность команд помещает в текст программы

    макрокоманды определения команд сопроцессора 8087 во время первого

    прохода ассемблера, когда должны обрабатываться макрорасширения.

    Ассемблер не читает файл макрокоманд во время второго прохода, так

    как этот файл больше не нужен.  В листинге ассемблера появляется

    только команда ENDIF.

      Первая команда пересылки данных, которую мы рассмотрим -

    команда загрузки.  Название всех команд сопроцессора 8087

    начинается с буквы "F".  Так что, чтобы загрузить число в

    микросхему 8087, используется команда FLD (Floating LoaD, плавающая

    загрузка).    В отличие от команд микропроцессора 8088, где команда

    MOV обслуживает все форматы данных, здесь существует разная

           Microsoft (R) Macro Assembler Version 5.00                1/1/80 01:21:45

             Фиг. 7.10 Команды пересылки сопроцессора 8087           Page     1-1

 

                                           PAGE    ,132

                                           TITLE   Фиг. 7.10 Команды пересылки сопроцессора 8087

            0000                     CODE    SEGMENT

                                           ASSUME  CS:CODE,DS:CODE

 

            0000                     WORD_INTEGER    LABEL   WORD

            0000                     SHORT_INTEGER   LABEL   DWORD

            0000                     LONG_INTEGER    LABEL   QWORD

            0000                     BCD_INTEGER     LABEL   TBYTE

            0000                     SHORT_REAL      LABEL   DWORD

            0000                     LONG_REAL       LABEL   QWORD

            0000                     TEMPORARY_REAL  LABEL   TBYTE

 

            0000  9B DF 06 0000 R                FILD    WORD_INTEGER

            0005  9B DB 06 0000 R                FILD    SHORT_INTEGER

            000A  9B DF 2E 0000 R                FILD    LONG_INTEGER

            000F  9B DF 26 0000 R                FBLD    BCD_INTEGER

            0014  9B D9 06 0000 R                FLD     SHORT_REAL

            0019  9B DD 06 0000 R                FLD     LONG_REAL

            001E  9B DB 2E 0000 R                FLD     TEMPORARY_REAL

 

            0023  9B D9 C2                       FLD     ST(2)

 

            0026  9B DF 16 0000 R                FIST    WORD_INTEGER

            002B  9B DB 16 0000 R                FIST    SHORT_INTEGER

            0030  9B D9 16 0000 R                FST     SHORT_REAL

            0035  9B DD 16 0000 R                FST     LONG_REAL

 

            003A  9B DD D2                       FST     ST(2)

 

            003D  9B DF 1E 0000 R                FISTP   WORD_INTEGER

            0042  9B DB 1E 0000 R                FISTP   SHORT_INTEGER

            0047  9B DF 3E 0000 R                FISTP   LONG_INTEGER

            004C  9B DF 36 0000 R                FBSTP   BCD_INTEGER

            0051  9B D9 1E 0000 R                FSTP    SHORT_REAL

            0056  9B DD 1E 0000 R                FSTP    LONG_REAL

            005B  9B DB 3E 0000 R                FSTP    TEMPORARY_REAL

 

            0060  9B DD DA                       FSTP    ST(2)

            0063  9B D9 CA                       FXCH    ST(2)

 

            0066  9B D9 EE                       FLDZ

            0069  9B D9 E8                       FLD1

            006C  9B D9 EB                       FLDPI

            006F  9B D9 E9                       FLDL2T

            0072  9B D9 EA                       FLDL2E

            0075  9B D9 EC                       FLDLG2

            0078  9B D9 ED                       FLDLN2

 

            007B                     CODE    ENDS

                                           END

          Фиг. 7.10 Команды пересылки сопроцессора 8087

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

    ассемблер может различать четырехбайтовые и восьмибайтовые

    операнды, но не может знать, является ли операнд действительным или

    целым числом.

 

      Всякий раз, когда операнд - целое, используется команда FILD.

    Итак, FILD загружает слово (16 бит), короткое целое число (32 бита)

    или длинное целое число (64 бита).    Чтобы загрузить упакованное

    десятичное число (80 бит), используется команда FBLD.  Буква B

    указывает десятичные числа.  Наконец, команда FLD загружает

    действительные числа.  Ассемблер определяет, какой вид целого или

    действительного числа вы желаете использовать.

 

      В ассемблере для имен команд сопроцессора 8087, ссылающихся к

    памяти, используется соглашение о том, что в случае целых чисел

    вслед за буквой F следует буква I, в случае десятичных чисел -

    буква B, и никакой буквы не следует в случае действительных чисел.

    Мы увидим, что то же соглашение используется и в командах записи, и

    в арифметических командах, которые указывают операнд в памяти.

 

      Как видно из Фиг. 7.10, для каждого из семи обслуживаемых

    сопроцессором 8087 типов данных существует команда загрузки.

    Команда загрузки указывает поле данных в памяти, микросхема 8087

    преобразует данные из их внешнего представления во временный

    действительный формат.  Преобразованное число помещается в стек,

    увеличивая его объем на единицу.  Если вы попытаетесь поместить

    число в стек, который уже содержит восемь чисел, сопроцессор 8087

    сообщит об особой ситуации - переполнении стека.  Если программа не

    обрабатывает особую ситуацию в своей собственной подпрограмме,

    встроенный обработчик особой ситуации пометит загруженное значение,

    как "неопределенное".  Это означает, что дальнейшие действия с этим

    числом дадут неопределенные результаты.  Если вы сделаете ошибку,

    сопроцессор 8087 проследит за тем, чтобы она не осталась

    незамеченной.

 

      Оставшаяся разновидность команды загрузки берет один из

    элементов стека и помещает его в стек.  Например, команда

 

      FLD    ST0

 

      дублирует вершину стека.  После нее два верхних элемента имеют

    одинаковые значения.  Команда

 

      FLD    ST3

 

      помещает копию четвертого элемента стека в стек.  Заметим, что

    число, которое было раньше ST3, стало теперь ST4.

 

      Давайте посмотрим на машинный язык, в действительности

    формируемый этими командами.  Поскольку этот текст порождает

    команды процессора 8087 с помощью макрокоманд, сравнительно легко

    увидеть, откуда появляются различные части команд.      Во=первых,

    каждая команда начинается с байта 09BH.  Это - команда WAIT.  Как

    вы помните, сопроцессор 8087 должен быть синхронизирован с работой

    микропроцессора 8088.  Если микропроцессор 8088 попытается

    выполнить следующую команду сопроцессора 8087 до того, как

    сопроцессор 8087 завершит текущую команду, действия микросхемы 8087

    дадут неверный результат.      Фактически все макрокоманды 8087

    содержат команду WAIT для обеспечения синхронизации.  (Команды без

    синхронизации сопроцессора 8087 - это все команды управления,

    обычно не требеющие ожидания результата.  Эти команды можно легко

    отличить так как они все начинаются с FN, где буква N означает

    отсутствие синхронизации).

 

      По макрорасширениям также можно видеть, что команды процессора

    8087 формируются командами ESC.  Чтобы указать адрес памяти,

    команда ESC имеет два операнда.  Первый определяет, какая это

    команда ESC, а второй ссылается на ячейку памяти.  Команда ESC

    может иметь длину два, три или четыре байта, в зависимости от

    размера поля индексного смещения, сопровождающего байт mod=r/m.  В

    комбинации с командой WAIT максимальная длина команды сопроцессора

    8087 достигает пяти байт.

 

      Команда записи имеет два варианта.  Первый вариант этой команды

    извлекает число с вершины стека и записывает ее в поименованную

    ячейку памяти.  Выполняя эту команду, сопроцессор 8087 делает

    преобразование данных из временного действительного формата в

    желаемую внешнюю форму.  Эта команда имеет коды операций FST и

    FIST.  (Заметим, что здесь продолжают свое действие соглашения об

    именах команд).  Этой же командой вы можете занести вершину стека в

    любое место внутри стека.

 

      Вероятно вы заметили, что команда FST не допускает запись всех

    возможных внешних типов данных.  Допустимы лишь типы из "большой

    четверки" - целое слово, короткое целое, короткое и длинное

    действительные.  Эта команда не поддерживает все внешниие типы

    данных, потому что создатели процессора 8087 понимали, что это не

    обязательно из=за свойств следующей команды.

 

      Второй вариант команды записи, кроме записи данных, также

    изменяет положение указателя стека.  Команды FSTP (а также команды

    FISTP и FBSTP) выполняют ту же операцию записи данных из

    сопроцессора 8087 в память, но они также извлекают число из стека.

    Эта разновидность команд поддерживает все внешние типы данных.

    Конструкторы микросхемы 8087 кое=где экономили на командах, и

    поэтому только команды FLD и FSTP поддерживают все внешние типы

    данных.  Все остальные команды сохранения данных в памяти работают

    только с "большой четверкой" типов данных.  Конструкторы понимали,

    что эти четыре типа будут преобладать над всеми, и использование

    других форматов может быть реализовано только командами FLD и FSTP.

 

      Команда замены FXCH - следующая команда в группе команд

    пересылки данных.  Команда FXCH меняет местами содержимое вершины

    стека с содержимым другого регистра стека.  Эта команда может

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

    Нельзя одной командой поменять местами содержимое вершины стека и

    ячейки памяти.  Эта процедура потребует несколько команд и рабочее

    поле где=то в памяти.  В отличие от микропроцесоора 8088,

    сопроцессор 8087 может в одной команде выполнить чтение из памяти

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

      Команда     Константа

      --------------------------

        FLDZ            0

        FLD1            1

        FLDPI     PI

        FLDL2T    LOG2(10)

        FLDL2E    LOG2(e)

        FLDG2     LOG10(2)

        FLDLN2    LOGe(2)

      -------------------------- Фиг. 7.11 Константы 8087

 

      Остальные команды группы команд персылки данных обслуживают

    константы.    Они загружают в стек заранее известные значения.  Эти

    константы описывают набор величин, необходимых программам при

    вычислениях, и были выбраны из соображений упрощения счета

    трансцендентных и тригонометрических функций.  Мы используем

    некоторые из этих констант в демонстрационных программах.  Таблица

    на Фиг. 7.11 показывает, какое именно значение загружается в элемент

    ST0 в случае каждой команды.  В каждом случае мнемоника команды

    выбрана так, чтобы отражать значение константы.

 

             Microsoft (R) Macro Assembler Version 5.00              1/1/80 04:04:07

             Фиг. 7.12 Команды управления сопроцессора 8087          Page     1-1

 

                                           PAGE    ,132

                                           TITLE   Фиг. 7.12 Команды управления сопроцессора 8087

            0000                     CODE    SEGMENT

                                           ASSUME  CS:CODE

 

            0000                     STATUS_WORD     LABEL   WORD

            0000                     CONTROL_WORD    LABEL   WORD

            0000                     ENVIRONMENT     LABEL   BYTE        ; Область размером 14 байт

            0000                     STATE             LABEL   BYTE            ; Область размером 94 байта

 

            0000  9B DB E3                       FINIT

            0003  9B DB E0                       FENI

            0006  9B DB E1                       FDISI

            0009  9B 2E: D9 2E 0000 R            FLDCW   CONTROL_WORD

            000F  9B 2E: D9 3E 0000 R            FSTCW   CONTROL_WORD

            0015  9B DB E2                       FCLEX

            0018  9B 2E: D9 36 0000 R            FSTENV  ENVIRONMENT

            001E  9B 2E: D9 26 0000 R            FLDENV  ENVIRONMENT

            0024  9B 2E: DD 36 0000 R            FSAVE   STATE

            002A  9B 2E: DD 26 0000 R            FRSTOR  STATE

            0030  9B D9 F7                       FINCSTP

            0033  9B D9 F6                       FDECSTP

            0036  9B DD C2                       FFREE   ST(2)

            0039  9B D9 D0                       FNOP

            003C  9B                       FWAIT

            003D                     CODE    ENDS

                                           END

 

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

Hosted by uCoz