Система команд сопроцессора

Язык ассемблера / Система команд сопроцессора

Система команд сопроцессора включает в себя около 80 машинных команд, включающих в себя

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

  • все мнемонические обозначения начинаются с символа f (float);
  • вторая буква мнемонического обозначения определяет тип операнда в памяти, с которым работает команда: - i — целое двоичное число; - b — целое десятичное число; - отсутствие буквы — вещественное число;
  • последняя буква мнемонического обозначения команды р означает, что последним действием команды обязательно является извлечение операнда из стека;
  • последняя или предпоследняя буква r (reversed) означает реверсивное следование операндов при выполнении команд вычитания и деления, так как для них важен порядок следования операндов.

Система команд сопроцессора отличается большой гибкостью в выборе вариантов задания команд, реализующих определенную операцию, и их операндов. Минимальная длина команды сопроцессора — 2 байта. Все команды сопроцессора оперируют регистрами стека сопроцессора. Если операнд в команде не указывается, то по умолчанию используется вершина стека сопроцессора (логический регистр st(0)). Если команда выполняет действие с двумя операндами по умолчанию, то эти операнды – регистры st(0) и st(1).

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

Группа команд передачи данных предназначена для организации обмена между регистрами стека, вершиной стека сопроцессора и ячейками оперативной памяти. Команды этой группы имеют такое же значение для процесса программирования сопроцессора, как и команда mov основного процессора. С помощью этих команд осуществляются все перемещения значений операндов в сопроцессор и из него. По этой причине для каждого из трех типов данных, с которыми может работать сопроцессор, существует своя подгруппа команд передачи данных. Собственно на этом уровне все его умения по работе с различными форматами данных и заканчиваются. Главной функцией всех команд загрузки данных в сопроцессор является преобразование их к единому представлению в виде вещественного числа расширенного формата. Это же касается и обратной операции — сохранения в памяти данных из сопроцессора. Команды передачи данных можно разделить на следующие группы:

  • команды передачи данных в вещественном формате;
  • команды передачи данных в целочисленном формате;
  • команды передачи данных в двоично-десятичном формате.

Основными командами передачи данных являются

  • команда FLD (загрузка данных в вершину стека сопроцессора);
  • команда FST (сохранение вершины стека сопроцессора в память)

и их модификации. Команды передачи данных вещественного типа Используются в случае если операнд, применяемый в команде, имеет вещественный тип (4, 8 или 10-байтный).

Команда Операнды Пояснение Описание
FLD src TOPSWR-=1; ST(0)=src; Загрузка операнда в вершину стека
FST dst dst=ST(0); Сохранение вершины стека в память
FSTP dst dst=ST(0); TOPSWR+=1; Сохранение вершины стека в память с выталкиванием
FXCH ST(i) ST(0) ↔ ST(i) Обмен значений ST(0) и ST(i)

Команды передачи данных целого типа Используются в случае если операнд, применяемый в команде, имеет целый тип (1, 2, 4 или 8-байтный).

Команда Операнды Пояснение Описание
FILD src TOPSWR-=1; ST(0)=src; Загрузка операнда в вершину стека
FIST dst dst=ST(0); Сохранение вершины стека в память
FISTP dst dst=ST(0); TOPSWR+=1; Сохранение вершины стека в память с выталкиванием

Команды передачи данных двоично-десятичного типа Используются в случае если операнд, применяемый в команде, представлен в двоично-десятичной системе счисления (1, 2, 4 или 8-байтный).

Команда Операнды Пояснение Описание
FBLD src TOPSWR-=1; ST(0)=src; Загрузка операнда в вершину стека
FBSTP dst dst=ST(0); TOPSWR+=1; Сохранение вершины стека в память с выталкиванием

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

Команда Пояснение Описание
FLDZ TOPSWR-=1; ST(0)=0; Загрузка 0
FLD1 TOPSWR-=1; ST(0)=1; Загрузка 1
FLDPI TOPSWR-=1; ST(0)=3.1415926535; Загрузка π
FLDL2T TOPSWR-=1; ST(0)=3.3219280948; Загрузка log210
FLDL2E TOPSWR-=1; ST(0)=1.4426950408; Загрузка log2e
FLDLG2 TOPSWR-=1; ST(0)=0.3010299956; Загрузка lg 2
FLDLN2 TOPSWR-=1; ST(0)=0.6931471805; Загрузка ln 2

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

Команды данной группы выполняют сравнение значений числа в вершине стека и операнда, указанного в команде. Команды сравнения данных вещественного типа

Команда Операнды Пояснение Описание
FCOM FUCOM src ST(0) - src Вещественное сравнение
FCOMP FUCOMP src ST(0) - src; TOPSWR+=1; Вещественное сравнение с выталкиванием
FCOMPP FUCOMPP - ST(0) - ST(1); TOPSWR+=2; Вещественное сравнение с двойным выталкиванием
FCOMI FUCOMI ST, ST(i) ST(0) - ST(i) Вещественное сравнение c модификацией EFLAGS
FCOMIP FUCOMIP ST, ST(i) ST(0) - ST(i); TOPSWR+=1; Вещественное сравнение c выталкиванием с модификацией EFLAGS
FXAM - Анализ ST(0)

Команды сравнения сравнивают значение в вершине стека с операндом. По умолчанию (если операнд не задан) происходит сравнение регистров ST(0) и ST(1). В качестве операнда может быть задана ячейка памяти или регистр. Команда устанавливает биты C0, C2, C3 регистра swr в соответствии с таблицей. Сбрасывает в 0 признак C1 при пустом стеке после выполнения команды.

Условие С3 С2 C0
ST(0) > src 0 0 0
 ST(0) < src  0 0 1
 ST(0) = src  1 0 0
 Недопустимая операция (#IA)  1 1 1

Особый интерес представляет команда FCOMI (FUCOMI). Она сравнивает содержимое регистра ST(0) со значением операнда ST(i) и устанавливает биты ZF, PF, CF регистра EFLAGS в соответствии с таблицей. Анализ выполнения сравнения осуществляет последующая команда условного перехода (команда центрального процессора).

Условие ZF PF CF Переход
 ST(0) > ST(i)  0 0 0  ja
 ST(0) < ST(i)  0 0 1  jb
  ST(0) = ST(i)  1 0 0  je
  ST(0) >= ST(i)  * 0 0  jae
  ST(0) <= ST(i)  * 0 *  jbe
 Недопустимая операция (#IA)  1  1 1

Команда FXAM проверяет содержимое регистра ST(0) и устанавливает биты C0, C2, C3 регистра swr в соответствии с таблицей. Бит C1 устанавливается равным знаковому биту ST(0).

Класс С3 С2 C0
Неподдерживаемый формат 0 0 0
Нечисло (NaN) 0 0 1
Конечное число 0 1 0
Бесконечность 0 1 1
Ноль 1 0 0
Пустой регистр 1 0 1
Ненормированное число 1 1 0

Команды сравнения данных целого типа

Команда Операнды Пояснение Описание
FICOM src ST(0) - src Cравнение с целым числом src
FICOMP src ST(0) - src; TOPSWR+=1; Cравнение с целым числом src с выталкиванием
FTST - ST(0)-0; Анализ ST(0) (сравнение с нулем)

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

Команды сопроцессора, входящие в данную группу, реализуют четыре основные арифметические операции — сложение, вычитание, умножение и деление. Имеется также несколько дополнительных команд, предназначенных для повышения эффективности использования основных арифметических команд. С точки зрения типов операндов, арифметические команды сопроцессора можно разделить на команды, работающие с вещественными и целыми числами. Арифметические команды вещественного типа Схема расположения операндов вещественных команд традиционна для команд сопроцессора. Первый операнд по умолчанию (если не указан в команде) располагается в вершине стека сопроцессора — регистре ST(0), и на его место после выполнения команды записывается результат. Второй операнд может быть расположен либо в памяти, либо в другом регистре стека сопроцессора. По умолчанию в качестве второго операнда используется регистр ST(1). Допустимыми типами операндов в памяти являются вещественные форматы простой и двойной точности. В отличие от целочисленных арифметических команд, вещественные арифметические команды допускают большее разнообразие в сочетании местоположения операндов и самих команд для выполнения конкретного арифметического действия.

Команда Операнды Пояснение Описание
FADD dst, src dst = dst + src; Сложение вещественное
FADDP ST(i), ST(0) ST(i) = ST(i) + ST(0); TOPSWR+=1; Сложение вещественное с выталкиванием
FSUB dst, src dst = dst - src; Вычитание вещественное
FSUBP ST(i), ST(0) ST(i) = ST(i) - ST(0); TOPSWR+=1; Вычитание вещественное с выталкиванием
FSUBR dst, src dst = src - dst; Вычитание вещественное реверсивное
FSUBRP ST(i), ST(0) ST(i) = ST(0) - ST(i); TOPSWR+=1; Вычитание вещественное реверсивное с выталкиванием
FMUL dst, src dst = dst * src; Умножение вещественное
FMULP ST(i), ST(0)  ST(i) = ST(i) * ST(0); TOPSWR+=1;  Умножение вещественное с выталкиванием
FDIV dst, src dst = dst / src; Деление вещественное
FDIVP ST(i), ST(0)  ST(i) = ST(i) / ST(0); TOPSWR+=1; Деление вещественное с выталкиванием
FDIVR dst, src dst = src /dst; Деление вещественное реверсивное
FDIVRP ST(i), ST(0)  ST(i) = ST(0) / ST(i); TOPSWR+=1; Деление вещественное реверсивное с выталкиванием

Арифметические команды целого типа Целочисленные арифметические команды предназначены для работы на тех участках вычислительных алгоритмов, где в качестве исходных данных используются целые числа в памяти, имеющие размерность 4 или 8 байт. Перед выполнением команды целочисленное значение преобразуется к вещественному формату двойной расширенной точности (80 бит).

Команда Операнды Пояснение Описание
FIADD src ST(0) = ST(0) + src; Сложение целочисленное
FISUB src ST(0) = ST(0) - src; Вычитание целочисленное
FISUBR src ST(0) = src - ST(0); Вычитание целочисленное реверсивное
FIMUL src ST(0) = ST(0) * src; Умножение целочисленное
FIDIV src ST(0) = ST(0) / src; Деление целочисленное
FIDIVR src ST(0) = src / ST(0); Деление целочисленное реверсивное

Дополнительные арифметические команды Команды этой группы не имеют операндов, производят действие с операндом в вершине стека сопроцессора. Результат выполнения операции сохраняется в регистре ST(0). Сбрасывают в 0 признак C1 при пустом стеке, устанавливают в 1 при округлении результата.

Команда Пояснение Описание
FSQRT ST(0) = √ST(0) Вычисление квадратного корня
FABS ST(0) = |ST(0)| Вычисление модуля
FCHS ST(0) = -ST(0) Изменение знака
FXTRACT temp = ST(0); ST(0)=порядок(temp); TOP-=1; ST(0)=мантисса(temp); Выделение порядка и мантиссы
FSCALE ST(0) = ST(0) · 2ST(1) Масштабирование по степеням 2
FRNDINT ST(0)=(ST(0)) Округление ST(0)
FPREM ST(0)=ST(0)-Q*ST(1) Частичный остаток от деления
FPREM1

Команда FXTRACT – выделение порядка и мантиссы. Операнд-источник по умолчанию, хранящийся в регистре ST(0), разделяется на порядок и мантиссу, порядок сохраняется в ST(0), а затем мантисса помещается в стек, меняя при этом указатель вершины стека (поле top). Для операнда, хранящего мантиссу, знак и мантисса остаются неизменными по сравнению с операндом источника. Вместо порядка записывается 3FFFh. После выполнения команды регистр ST(1) хранит значение порядка исходного операнда. Команда FSCALE– команда масштабирования: изменяет порядок значения, находящегося в вершине стека сопроцессора ST(0) на величину ST(1). Команда не имеет операндов. Величина в ST(1) рассматривается как число со знаком. Его прибавление к полю порядка вещественного числа в ST(0) означает его умножение на величину 2ST(1). С помощью данной команды удобно масштабировать на степень двойки некоторую последовательность чисел в памяти. Для этого достаточно последовательно загружать числа в вершину стека, после чего применять команду FSCALE и сохранять значения обратно в памяти. Команда FRNDINT – округляет значение, находящееся в вершине стека сопроцессора ST(0). Команда не имеет операндов. Сопроцессор имеет программно-аппаратные средства для выполнения операции округления тех результатов работы команд, которые не могут быть точно представлены. Но операция округления может быть проведена и принудительно к значению в регистре ST(0), для этого предназначена последняя команда в группе дополнительных команд — команда округления. Возможны четыре режима округления величины в ST(0), которые определяются значениями в поле RC управляющего регистра CWR. Для изменения режима округления используются команды FSTCWR и FLDCWR, которые, соответственно, записывают в память содержимое управляющего регистра сопроцессора и восстанавливают его обратно. Таким образом, пока содержимое этого регистра находится в памяти, можно установить необходимое значение поля RC. Команда FPREM – получение частичного остатка от деления. Исходные значения делимого и делителя размещаются в стеке — делимое в ST(0), делитель в ST(1). Команда производит вычисления по формуле

ST(0)=ST(0)-Q*ST(1),

где Q – целочисленное частное от деления. Делитель рассматривается как некоторый модуль. Поэтому в результате работы команды получается остаток от деления по модулю. Физически работа команды заключается в реализации деление в столбик. При этом каждое промежуточное деление осуществляется отдельной командой FPREM. Цикл, центральное место в котором занимает команда FPREM, завершается, когда очередная полученная разность в ST(0) становится меньше значения модуля в ST(1). Судить об этом можно по состоянию флага С2 в регистре состояния swr:

  • если С2=0, то работа команды fprem полностью завершена, так как разность в ST(0) меньше значения модуля в ST(1);
  • если С2=1, то необходимо продолжить выполнение команды fprem, так как разность в ST(0) больше значения модуля в ST(1).

Таким образом, необходимо анализировать флаг С2 в теле цикла. Для этого С2 записывается в регистр флагов основного процессора с последующим анализом его командами условного перехода. Другой способ заключается в сравнении ST(0) и ST(1). Команда fprem не соответствует последнему стандарту на вычисления с плавающей точкой IEEE-754. По этой причине в систему команд сопроцессора i387 была введена команда fprem1, которая отличается от FPREM тем, что накладывается дополнительное требование на значение остатка в ST(0). Это значение не должно превышать половины модуля в ST(1). После полного завершения работы команды FPREM/FPREM1 (когда С2=0), биты С0, С3, С1 содержат значения трех младших разрядов частного.

Команды трансцендентных функций

Сопроцессор имеет ряд команд, предназначенных для вычисления значений тригонометрических функций, а также значений логарифмических и показательных функций. Значения аргументов в командах, вычисляющих результат тригонометрических функций, должны задаваться в радианах. Данная группа команд не имеет операндов. Результат сохраняется в регистре ST(0). Сбрасывает в 0 признак C1 при пустом стеке, устанавливают в 1 при округлении. Признак C2 устанавливается в 1 при выходе значения угла за границы диапазона [-263; 263].

Команда Пояснение Описание
FSIN ST(0) = sin(ST(0)) Вычисление синуса
FCOS ST(0) = cos(ST(0)) Вычисление косинуса
FSINCOS temp=ST(0); ST(0)=sin(temp); TOP-=1; ST(0)=cos(temp); Вычисление синуса и косинуса
FPTAN ST(0)=tg(ST(0)); TOP-=1; ST(0)=1.0; Вычисление тангенса
FPATAN ST(1)=atan(ST(1)/ST(0)); TOP+=1; Вычисление арктангенса
F2XM1 ST(0)=2ST(0)-1; Вычисление выражения y=2x-1
FYL2X x=ST(0); y=ST(1); TOP+=1; ST(0)=y*log2x; Вычисление выражения y*log2x
FYL2XP1 x=ST(0); y=ST(1); TOP+=1; ST(0)=y*log2(x+1);  Вычисление выражения y*log2(x+1)

Команда FPTAN – вычисляет частичный тангенс угла: ST(1)=tg(ST(0)), ST(0)=1. Это сделано для совместимости с сопроцессорами 8087 и 287. Выполнение данной команды в них имело следующую особенность: результат команды возвращался в виде двух значений — в регистрах ST(0) и ST(1). Ни одно из этих значений не является истинным значением тангенса. Истинное его значение получается лишь после операции деления ST(0)/ST(1). Таким образом, для получения тангенса требовалась еще команда деления. Синус и косинус в ранних версиях сопроцессоров вычислялись через тангенс половинного угла. В микропроцессоре i387 появились самостоятельные команды для вычисления синуса и косинуса, вследствие чего отпала необходимость составлять соответствующие подпрограммы. Что же до команды fptan, то она по-прежнему выдает два значения в st(0) и st(1), но значение в st(0) всегда равно 1, а в st(1) находится истинное значение тангенса числа, находившегося в st(0) до выполнения команды fptan. Команда FPATAN вычисляет частичный арктангенс угла: . Команда не имеет операндов. Результат возвращается в регистр ST(1), после чего производится выталкивание вершины стека. Команда FPATAN широко применяется для вычисления значений обратных тригонометрических функций (arcsin, arccos, arcctg, arccosec, arcsec). Для вычисления функции arcsin используется формула: asinДля вычисления функции arccos используется формула: acosДля вычисления функции arcctg используется формула: actgДля вычисления этих функций необходимо выполнить следующую последовательность шагов:

  • Если а является мерой угла в градусах, то выполнить ее преобразование в радианную меру.
  • Вычислить значение выражения числителя и поместить его в стек.
  • Вычислить значение выражения знаменателя и поместить его в стек.
  • Выполнить команду fpatan с аргументами в st(0)=знаменатель и st(1)=числитель.

В результате этих действий в регистре ST(0) будет сформировано значение, которое и будет являться значением требуемой функции. Команда F2XM1 вычисляет значение функции: 2x-1. Исходное значение x размещается в вершине стека сопроцессора ST(0) и должно лежать в диапазоне [-1; 1]. Результат замещает значение в регистре ST(0). Эта команда может быть использована для вычисления показательных функций. 1 вычитается для того, чтобы получить точный результат, когда x близок к нулю. Поскольку нормированное число всегда содержит в качестве первой значащей цифры единицу, если в результате вычисления функции получается число 1,000000000456..., то команда F2XM1, вычитая 1 из этого числа, и затем, нормируя результат, формирует больше значащих цифр, то есть делает его более точным. Неявное вычитание единицы командой F2XM1 компенсируется командой FADD с единичным операндом. Команда FYL2X вычисляет значение функции ST(0)=ST(1)·log2ST(0). Значение х должно лежать в диапазоне [0;∞). Перед тем, как осуществить запись результата в вершину стека, команда FYL2X выталкивает значения x и у из стека, и только после этого производит запись результата в стек. Команда FYL2XP1–вычисляет ST(0)=ST(1)·log2(ST(0)+1). Значение х должно лежать в диапазоне [0;∞). Поскольку специальной команды в сопроцессоре для операции возведения в степень нет, возведение в произвольную степень числа с любым основанием производится по формуле:

xy=2y·log2x

Вычисление значения выражения z=y·log2x для любых y>0 и x>0 производится командой сопроцессора FYL2X. Вычисление 2z-1 производится командой F2XM1. Лишнее действие вычитания 1 можно компенсировать сложением с единицей. Но в последнем действии есть тонкий момент, который связан с тем, что величина аргумента x должна лежать в диапазоне: [-1; 1]. В случае, если x превышает это значение (например, для вычисления 163) при вычислении выражения 3·log216 командой FYL2X, получим в стеке значение 12. Попытка вычислить значение 212 командой F2XM1 ни к чему не приведет — результат будет не определен. В этой ситуации используется команда сопроцессора FSCALE, которая  вычисляет значение выражения 2х, но для целых значений x со знаком. Применив формулу

2a+b = 2a·2b,

получаем решение проблемы. Разделяем дробный показатель степеней больших 1 по модулю на две части — целую и дробную. После этого вычисляем отдельно командами FSCALE и F2XM1 степени двойки и перемножаем результаты.

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

Данная группа команд предназначена для общего управления работой сопроцессора. Команды этой группы имеют особенность — перед началом своего выполнения они не проверяют наличие незамаскированных исключений. Однако такая проверка может понадобиться, в частности для того, чтобы при параллельной работе основного процессора и сопроцессора предотвратить разрушение информации, необходимой для корректной обработки исключений, возникших в сопроцессоре. Поэтому некоторые команды управления имеют аналоги, выполняющие те же действия плюс одну дополнительную функцию — проверку наличия исключения в сопроцессоре. Эти команды имеют одинаковые мнемокоды (и машинные коды тоже), отличающиеся только вторым символом N:

  • мнемокод, не содержащий второго символа N, обозначает команду, которая перед началом своего выполнения проверяет наличие незамаскированных исключений;
  • мнемокод, содержащий второй символ N, обозначает команду, которая перед началом своего выполнения не проверяет наличия незамаскированных исключений, то есть выполняется немедленно, что позволяет сэкономить несколько машинных тактов.

Эти команды имеют одинаковый машинный код. Отличие лишь в том, что перед командами, не содержащими символа N, транслятор ассемблера вставляет команду wait. Команда wait является полноценной командой основного процессора и ее, при необходимости, можно указывать явно. Команда wait имеет аналог среди команд сопроцессора — fwait.

Команда Операнды Пояснение Описание
FWAIT - - Синхронизация работы с центральным процессором
FINIT FNINIT - CWR=037Fh; SWR=0; TWR=FFFFh; DPR=0; IPR=0; Инициализация сопроцессора
FSTSW FNSTSW dst AX dst=SWR; AX = SWR; Считать слово состояния сопроцессора в память
FSTCW FNSTCW dst AX dst=СWR; AX = CWR; Считать слово управления сопроцессора в память
FLDCW src CWR=src; Загрузить слово управления сопроцессора
FCLEX FNCLEX - SWR=SWR & 7F00h Сброс флагов исключений
FINCTSP - TOP+=1; Увеличение указателя стека сопроцессора на 1
FDECSTP - TOP-=1; Уменьшение указателя стека сопроцессора на 1
FFREE ST(i) TAG(i)=11b Очистка указанного регистра
FNOP - - Пустая операция
FSAVE FNSAVE dst ... Сохранение состояния среды сопроцессора
FRSTOR src ... Восстановление состояния среды сопроцессора
FSTENV FNSTENV dst ... Частичное сохранение состо­яния среды сопроцессора
FLDENV src ... Восстановление частичного со­стояния среды сопроцессора

Команда FWAIT — команда ожидания. Предназначена для синхронизации работы процессора и сопроцессора. Так как основной процессор и сопроцессор работают параллельно, то может создаться ситуация, когда за командой сопроцессора, изменяющей данные в памяти, следует команда основного процессора, которой эти данные требуются. Чтобы синхронизировать работу этих команд, необходимо включить между ними команду wait/fwait. Встретив данную команду в потоке команд, основной процессор приостановит свою работу до тех пор, пока не поступит аппаратный сигнал о завершении очередной команды в сопроцессоре. Команда FINIT/FNINIT — инициализация сопроцессора. Данная команда инициализирует управляющие регистры сопроцессора определенными значениями: CWR = 037Fh

  • RC=00b; округление к ближайшему целому;
  • PM,UM,OM,ZM,DM,IM=1; все исключения не замаскированы;
  • PC=11b; максимальная точность 64 бита.

SWR = 0h – отсутствие исключений и указание на то, что физический регистр стека сопроцессора r0 является вершиной стека и соответствует логическому регистру ST(0); TWR = FFFFh – все регистры стека сопроцессора пусты; DPR=0; IPR=0. Данную команду используют перед первой командой сопроцессора в программе и в других случаях, когда необходимо привести сопроцессор в начальное состояние. Команда FSTSW/FNSTSW — сохранение содержимого регистра состояния swr в регистре ах или в ячейке памяти размером 2 байта. Эту команду целесообразно использовать для подготовки к условным переходам по описанной при рассмотрении команд сравнения схеме. Команда FSTCW/FNSTCW — сохранение содержимого регистра управления cwr в ячейке памяти размером 2 байта. Эту команду целесообразно использовать для анализа полей маскирования исключений, управления точностью и округления. В качестве операнда назначения не используется регистр ах, в отличие от команды FSTSW/FNSTSW. Команда FLDCW — загрузки значения ячейки памяти размером 16 бит в регистр управления cwr. Эта команда выполняет действие, противоположное командам FSTCW/FNSTCW. Команду целесообразно использовать для задания или изменения режима работы сопроцессора. Если в регистре состояния swr установлен любой бит исключения, то попытка загрузки нового содержимого в регистр управления cwr приведет к возбуждению исключения. По этой причине необходимо перед загрузкой регистра cwr сбросить все флаги исключений в регистре swr. Команда FCLEX/FNCLEX — позволяет сбросить флаги исключений, которые, в частности, необходимы для корректного выполнения команды FLDCW. Ее также применяют и в случаях, когда необходимо сбрасывать флаги исключений в регистре swr, например, в конце подпрограмм обработки исключений. Если этого не делать, то при исполнении первой же команды сопроцессора прерванной программы (кроме тех команд, которые имеют в названии своего мнемокода второй символ n) будет опять возбуждено исключение. PE, UE, OE, ZE, DE, IE, ES, SF и B биты регистра SWR равны 0. Команда FINCSTP — увеличение указателя стека на единицу (поле top) в регистре swr. Команда не имеет операндов. Действие команды fincstp подобно команде FST, но она извлекает значение операнда из стека "в никуда". Таким образом, эту команду можно использовать для выталкивания, ставшего ненужным операнда, из вершины стека. Команда работает только с полем top и не изменяет соответствующее данному регистру поле в регистре тегов twr, то есть регистр остается занятым и его содержимое из стека не извлекается. Команда FDECSTP — уменьшение указателя стека (поле top) в регистре swr. Команда не имеет операндов. Действие команды FDECSTP подобно команде FLD, но она не помещает значения операнда в стек. Таким образом, эту команду можно использовать для проталкивания внутрь стека операндов, ранее включенных в него. Команда работает только с полем top и не изменяет соответствующее данному регистру поле в регистре тегов twr, то есть регистр остается пустым. Команда FFREE —помечает любой регистр стека сопроцессора как пустой. Команда записывает в поле регистра тегов, соответствующего регистру ST(i), значение 11b, что соответствует, пустому регистру. При этом указатель стека (поле tор) в регистре swr и содержимое самого регистра не изменяются. Необходимость в этой команде может возникнуть при попытке записи в регистр ST(i), который помечен, как непустой. В этом случае будет возбуждено исключение. Для предотвращения этого применяется команда FFREE. Команда FNOP — пустая операция. Не производит никаких действий и влияет только на регистр указателя команды IPR. Команда FSAVE/FNSAVE — сохранения полного состояния среды сопроцессора в память по адресу, указанному операндом приемник. Размер области памяти зависит от размера операнда сегмента кода use16 или use32:

  • use16 — область памяти должна быть 94 байта: 80 байт для восьми регистров из стека сопроцессора и 14 байт для остальных регистров сопроцессора с дополнительной информацией;
  • use32 — область памяти должна быть 108 байт: 80 байт для восьми регистров из стека сопроцессора и 28 байт для остальных регистров сопроцессора с дополнительной информацией.

После выполнения сохранения состояния среды сопроцессора производится инициализация сопроцессора. coprocessor3 Команда FRSTOR — используется для восстановления полного состояния среды сопроцессора из области памяти, адрес которой указан операндом источник. Сопроцессор будет работать в новой среде сразу после окончания работы команды frstor. Команда FSTENV/FNSTENV — сохранение частичного состояния среды сопроцессора в область памяти, адрес которой указан операндом приемник. Размер области памяти зависит от размера операнда сегмента кода usel6 или use32. Формат области частичной среды сопроцессора совпадает с форматом области полной среды, за исключением содержимого стека сопроцессора (80 байт). Команда FLDENV — восстановление частичного состояния среды сопроцессора содержимым из области памяти, адрес которой указан операндом источник. Информация в данной области памяти была ранее сохранена командой FSTENV/FNSTENV. Команды сохранения среды целесообразно применять в обработчиках исключений, так как только с помощью данных команд можно получить доступ, например, к регистрам DPR и IPR. Не исключено использование этих команд при написании подпрограмм или при переключении контекстов программ в многозадачной среде. Назад

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *