Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
MProc / M3 / Программирование блока FPU в IA.doc
Скачиваний:
19
Добавлен:
16.04.2013
Размер:
249.86 Кб
Скачать

InCcntr; Инкремент счетчика

FIDIVcntr; Деление на 2i+1

FADDst[2],st; Накопление суммы членов ряда

СМР cntr,10 ; Контроль предельного значения счетчика

JBLSi; Переход, если расчет не закончен

FINCSTP; Освобождение стека сопроцессора

FINCSTP; Освобождение стека сопроцессора

FSTPresult; Сохранение результата

MOV AX,offset DGROUP:result

POPBP; Восстановление базового указателя стека

RET; Выход из подпрограммы

_Ехр ENDP

Здесь cntrдолжно быть определено какWORD,resultкакQWORDв сегменте данных. КомандыFINCSTPиFDECSTPприменяются для баланса стека сопроцессора и изменения значения его указателя, добавляя или вычитая единицу из указателя стека соответственно.

Аналогичным образом вычисляются и ряды для других функций, но с учётом их особенностей. Например, для синуса и косинуса R=(х*х)/2i(2i+1), т.е. здесь нужны манипуляции над числами, связанными с 2i. Эти числа удобнее всего строить, основываясь на хранении 2i (и 2i+1) в целой форме с последующими инкрементами в оперативной памяти.

Программирование сопроцессора с использованием операций вычисления частичных математических функций

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

FSQRT– заменяет аргумент вst[0] значением квадратного корня.

FABS– заменяет содержимоеst[0] его абсолютным значением.

FCHS– смена знака содержимогоst[0].

FRNDINT– округляет содержимоеst[0] до целого значения.

FXTRACT– расщепляет содержимоеst[0] на два числа: несмещен­ный порядок в формате с плавающей точкой, заменяющий аргумент, и мантиссу со знаком, дополнительно размещаемую в стеке после--st. КомандаFSCALEпослеFXTRACTвосстанавливает начальное число, но не восстанавливает указатель стека.

FSCALE- к значению порядка вst[0] добавляется целая часть числа изst[1] и таким образом восстанавливаются исходные данные командыFXTRACT, для компенсации изменений указателя стека нужно дополнительно выполнить командуFSTPst[1].

FCOS– заменяет аргумент вst[0] значением синуса для аргумента в радианах в пределах -263.. 263.

FSIN– заменяет аргумент вst[0] значением синуса для аргумента в радианах в пределах -263.. 263;

FSINCOS– заменяет аргумент вst[0] значением синуса для аргу­мента в радианах в пределах -263.. 263, затем выполняет --st и помещает в новую верхушку стека значения косинуса того же аргумента (выполняется быстрее отдельных функций).

FPREM- вычисляет частичный остаток от деленияst[0] наst[1] и размещает его вst[0]. Знакst[0] не изменяется, а если для получения окончательного результата достаточно меньше, чем 64 масштабирован­ные вычитания, то остаток, меньший модуля со знаком делимого, будет записан вst[0]. При этом три младших бита частного, позволяющие определить квадрант аргумента при делении на/2 помещаются в разряды С3,C1 и С0 регистраSW.

FPREM1 –то же, что и FPREM, но абсолютная величина остатка меньше половины модуля в соответствии со стандартомIEEE-754.

Процессоры ix87 могут вычислить любую элементарную трансцендентную функцию с аргументом, точность представления которого определяется содержимым регистра управления, и последующей выдачей результата такой же точности. В названиях команд и их описаниях принято обозначать аргументы, содержащиеся вst[0] как X, а вst[1] - какY. Результаты, формирующиеся вst[0], будем обозначать какx, а вst[1] - какy. Для упрощения восприятия этих команд, представленных в табл. 3, следует учитывать, что они разработаны с возможностью получения полного результата с помощью самой простой и естественной дополнительной команды.

Вычисление тригонометрических функций основано на выполнении команды FPTAN- нахождения частичного тангенса, которая в качестве результата дает два таких числа х и у, что у/х =tgX. Число у заменяет старое содержимоеst[0], а число х включается в стек дополнительно.

Таблица 3

Мнемоника команды

Название операции Вычислительная формула

Ограничения на аргументы

FPTAN

Частичный тангенс --st, у/х=tg Х

|Х| <263 :386

FPATAN

Частичный арктангенс

++st, x=arctg(Y/X)

нет ограничений

FYL2X

Вычисление логарифма

++st, Y*log2X

Х > 0

FYL2XP1

Вычисление логарифма

++st, Y*log2(X+1)

|X|<1 – 1/2

F2XM1

Вычисление Х =2x -1

1<=Х<=1

Вычисление тригонометрических функций первых математических сопроцессоров было основано на выполнении команды FPTAN– нахождения частичного тангенса, которая формирует результат в виде таких двух чисел х и у, что у/х=tgX. Число у заменяет старое содержимоеst[0], а число х добавляется к стеку дополнительно. Для вычисления значений тригонометрических функций сначала нужно отделить знак аргумента Х от значения; потом поделить на период π для тангенса, если х >= π/2, то изменить знак результата и значение аргумента на х-π, вычислить аргументz=х/2 и использовать формулы:

Обобщенный алгоритм вычисления трансцендентных функций по командам вычисления значений частичных функций выполняется как последовательность таких блоков:

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

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

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

Рассмотрим программирование вычисления тригонометрических функций с использованием их выражений через тангенс половинного угла. Эти формулы имеют неограниченный диапазон определения. Тангенс половинного угла имеет относительно аргумента zпериод π/2 и если организовать изменение знака, то достаточно использовать половинный аргумент.

При программировании тригонометрических функций диапазон значений аргумента можно свести к допустимому командой FPREMили проверить с помощью командыFXAM, так как он должен быть нормализованным и находиться в диапазоне 0<st[0]<π/4. Если аргументХлежит вне этого диапазона, то в начале программы необходимо выполнить преобразования аргумента к нужному диапазону и запомнить данные для обратного преобразования. Существуют несколько путей преобразования с использованием формул через тан­генс половинного угла и формул приведения значений тригонометрических функций. Наиболее эффективны пути, нашедшие наиболее полное отражение в системе команд сопроцессора.

Для функции tgXможно использовать 4 преобразования:

Х<0; S=signX; Y=|Х|; tgX= StgY; (1)

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

Y>; Z=Y – n ; tgY = tgZ; (2)

Здесь устраняется n-кратное повторение периода и дополнительных действий по восстановлению результата не требуется. Следующие два преобразования могут быть проведены в безусловной форме, так как модифицированный аргумент лежит в диапазоне 0Yπ.

U=Z/2; tgZ=(2tgU)/(1-tg2U); (3)

V=U/2; tgU=(2tgV)/(1-tg2V); (4)

Эти формулы, основанные на двукратном применении известной в математике универсальной тригонометрической подстановки через тангенс половинного угла, легко реализуются, так как деление на 2 быстро осуществляется командой FSCALE, и могут быть преобразованы с учетом того, что результат вычисления функцииFPTAN(V) сформирован в виде чисел х иy. Тогда

tgV=2xy/(x2-y2) иu=2xy;v=x2-y2(5)

где и/ v=tgV .

Эти формулы можно рассматривать как базовые для расчета тангенса и других тригонометрических функций с помощью команд FPTAN и FPREM, используя таблицу формул приведения и следующие формулы, выраженные через uиv.

sinY = (2u/v) / (1-(u/v)2);

cosY = (1-(u/v)2) / (1+(u/v)2);

cosecY = (1+(u/v)2) / 2uv;

secY = (1+(u/v)2) / (1-(u/v)2);

Пример процедуры вычисления тангенса, построенной по рассмотрен­ным формулам:

_tgPROC

PUSHBP;Стандартное сохранение указателя стека

MOVBP,SP;Установка нового значения указателя

FLDPI; Загрузка числа 

FLDQWORDPTR[BP+4]; Загрузка аргумента х

FTST

FSTSW stsw

PUSH stsw

rm:PREM; Исключение периода

FJp,rm; Циклическое исключение остатка

FLD1

FADDst,st; Формирование числа 2

FXCH st[1]

FSCALE; Деление на 4

FPTAN; Вычисление составляющих тангенса

FLDst[1]; Дублирование числителя

FMUL st,st ; Квадрат числителя (y*y)

FXCHst[1]; Обмен со знаменателем

FMUL st[2],st; Вычисление x*y

FMUL st,st ; Вычисление x*x

FSUBP st[1],st; Получение v

FMUL st,st[2]; Получение u

FLDst; Дублирование числителя u

FMUL st,st ; Квадрат числителя (u*u)

FXCHst[2]; Обмен со знаменателем

FMUL st[1],st; Вычисление (u*v)

FMUL st,st ; Вычисление (v*v)

FSUBPst[2],st; Получение знаменателя тангенса

FMULPst[2],st; Получение числителя тангенса

; Для следующей команды нужно предусмотреть

; защиту от особых ситуаций

FDIVPst[1],st; Получение значения тангенса

FSTPresult; Сохранение результата

MOV AX,offset DGROUP:result

POPBP; Восстановление базового указателя стека

RET; Выход из подпрограммы

_tg ENDP

Кроме рассмотренного способа тригонометрические функции могут вычисляться либо через тангенс половинного угла по формуле (3), либо через тангенс полного угла по формулам:

ctg x = 1 / tg x;

(7)

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

Команда FPATAN вычисляет arctg(st[1]/st[0])=arctg(Y/X). Два верхних элемента извлекаются из стека, а результат включается в стек. Операнды этой команды должны удовлетворять условию 0<Y<Х,иначе необходимо использовать формулы приведения:

arctg х = -arctg(-х), arctg х = π/2 - arctg (1/ x ). (8)

Остальные обратные тригонометрические функции находятся с по­мощью команд FPATAN,FSQRTи таких формул:

arctg z = arctg (Y/X);

arcctg z = arctg(1/z) = arctg(X/Y);

В этих формулах z- аргумент вычисляемой функции,X, Y -значения составного аргумента в регистрахst[0], st[1]перед выполнением командыFPATAN, результат которой помещается в вершину стека.

Формулы для вычисления логарифмических функций:

log2x => FYL2X при Y => FLD1, X => FLD х;

ln(x) => FYL2X при Y => FLDLN2, X => FLD x;

lg(x) => FYL2X при Y => FLDLG2, X => FLD x.

Команда FYL2X вычисляет st(1)*log2(st[0])приst[0]>0. Оба операнда извлекаются из стека, а затем результат помещается в стек. КомандыFLDL2E, FLDL2Tзагружают константы со значением двоичных логарифмов числаeи числа 10.

Еще одна логарифмическая команда FYL2XP1 вычисляетst[1](st[0]+1)приst[0]<1-1/2и используется для вычисления обратных гиперболических функций. КомандаF2XM1 вычисляет2st[0]-1, причем для аргумента должно выполняться условие:|st[0]|1

Формулы для вычисления обратных гиперболических функций ориентированы на использование команд вычисления логарифмов, квадратного корня и загрузки констант:

arsh х = sign x *ln 2* log2(1 + z ), где

archx=ln2*log2(1+z), гдеz=x-1+и х>1;

arth x = sign x - ln2 * log2(1+z), где z = 2|x| / (1-| x |) и -1< x< 1.

Для интервалов вне допустимых значений аргументов используются формулы приведения для обратных величин аргументов:

arcth x =arth (1/x); arcsh x =arsh (1/x); arsch x =arch (1/х).

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

ch(x) = 0.5(e|x| + 1/e|x|);

cth(x) = 1/th(x); csh(x) = 1/sh(x);

sch(x) = 1/ch(x);

Формулы для вычисления показательных функций:

2x = (2x-1) + 1 => F2XM1(x) + 1;

ex = 1 + 2x log2(e)-1 => 1+F2XM1(x*FLD2E);

10x = 1 + 2x log2(10)-1 => 1+F2XM1(x*FLD2T);

xy = 1 + 2y log2(x)-1 => 1+F2XM1(FYL2X(y,x)).

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

FLD1; Загрузка единицы

FLDx; Загрузка основания

FLDy; Загрузка показателя

FYL2X; Вычисление логарифма результата

FXTRACT; Расщепление на порядок и мантиссу

FXCH st[1]

FISTPtem; Сохранение порядка показателя

; В должно быть выделено целочисленное поле tmp

FIDIVqrt; Сведение диапазона делением на 4

; Поле qrt должно содержать целую константу 4

F2XM1; Вычисление показательной функции

FADD; Коррекция эксп-ты от мантиссы на 1

MOVCX,2; Корректирующая добавка к порядку

ADDCX,tem; Определение числа возведений в квадрат

m1:FMULst,st[0]; Циклическое повторение

LOOPm1; возведений в квадрат

К сожалению нельзя после команды FYL2Xпросто поставитьF2XM1сFADDи на этом завершить процедуру. Дело в том, что аргумент командыF2XM1должен быть по модулю меньше 1. Поэтому приходится применять эту команду только к мантиссе результата, а порядок учитывать через процедуру циклического возведения в квадрат. Для гарантии, упомянутая мантисса результата, заранее делится на 4, что потом компенсируется корректирующей добавкой к порядку.