- •Система команд fpu
- •Задание.
- •Лабораторная работа № 8 Вычисления с использованием математического сопроцессора
- •Задание.
- •Лабораторная работа № 9 Представление данных в математическом сопроцессоре
- •Особые случаи
- •1. Неточный результат
- •2. Численное антипереполнение или исчезновение порядка
- •3. Денормализованный операнд
- •4. Деление на нуль
- •5. Численное переполнение
- •6. Недействительная операция
- •Задание.
- •Литература
Задание.
1. Составить программу, состоящую из:
1.1 описания области в сегменте данных для сохранения контекста FPU по команде FNSTENV;
1.2 задания двух вещественных констант одинарной точности и одной целой 4-байтной константы 100;
1.3 в сегменте кода загрузить регистр сегмента значением начала области данных (@DATA);
1.4 прочитать значение регистров состояния, управления и тэгов, соответствующее состоянию начальной инициализации: для этого сохранить контекст FPU в описанной области из сегмента данных и для большей наглядности переслать из прямоадресуемых ячеек памяти в регистры ЦП три регистра FPU; пояснить установленные режимы и состояние регистра тэгов;
1.5 загрузить командой FLD три константы из сегмента данных (п. 1.2) как вещественные в стек данных, а так же включить в стек нуль и единицу; прочитать значения трех регистров аналогично п. 1.4: значения каких регистров изменились и почему?
2. В отчете привести текст программы и пояснения по п. 1.4-1.5:
2.1. Каково начальное состояние FPU?
2.2. Содержимое какого регистра не изменилось и почему?
2.3. Какие поля и флаги изменились и почему?
Лабораторная работа № 8 Вычисления с использованием математического сопроцессора
Для FPU базовыми арифметическими операциями являются представленные в табл. 8.1.
Таблица 8.1. Базовые арифметические операции
Мнемоника |
Название |
ADD |
Сложение |
SUB |
Вычитание |
SUBR |
Обратное вычитание |
MUL |
Умножение |
DIV |
Деление |
DIVR |
Обратное деление |
Обратные операции введены для того, чтобы сделать вычитание и деление симметричными, аналогичными сложению и умножению. В обычном виде первым операндом (приемник) указывается уменьшаемое или делимое, в обратном виде в качестве приемника выступает вычитаемое или делитель.
Из-за разных методов адресации и типов операндов арифметические команды могут иметь разные формы записи, представленные в табл. 8.2.
Таблица 8.2. Формы арифметических команд
Форма команды |
Мнемоника |
Операнд(ы) |
Пример |
Стековая |
Fop |
– |
FSUB |
Регистровая |
Fop |
ST(i),ST или ST,ST(i) |
FADD ST,ST(2) FDIV ST(5),ST |
Регистровая с извлечением |
FopP |
ST(i),ST |
FMULP ST(5),ST |
Вещественный операнд в памяти |
Fop |
<адрес> |
FADD X |
Целый операнд в памяти |
FIop |
<адрес> |
FIDIVR Y |
Здесь в качестве обозначения ор выступает одна из команд, приведенных в табл. 8.1.
Таким образом, если у команды нет операндов, то это эквивалентно записи операндов ST(1),ST, и операция выполняется над операндами из вершины стека. Если у команды один операнд, то это ячейка памяти, приемником (первым операндом) всегда является вершина стека, а эквивалентная запись операндов ST,<адрес>. Если два операнда, то работа производится со стеком. В любом случае один из операндов находится в вершине стека.
Часто операнд, находящийся в вершине стека, является промежуточным, и в дальнейшем не требуется. Регистровая форма с извлечением из стека использует операнд из вершины, а затем уничтожает его, инкрементируя указатель стека. То же происходит и при классической стековой форме операций: два операнда дают один результат с высвобождением одного регистра стека. В итоге команда FADD не эквивалентна команде FADD ST(1),ST, а является командой FADDP ST(1),ST.
Дополнительные арифметические команды операндов не имеют и работают с данными вершины стека. Их список приведен в табл. 8.3.
Таблица 8.3. Дополнительные арифметические команды
Мнемоника |
Описание |
FSQRT |
Извлечение квадратного корня |
FSCALE |
Масштабирование на степень числа 2 |
FPREM |
Нахождение частичного остатка |
FPREM1 |
Нахождение частичного остатка по стандарту IEEE754 |
FRNDINT |
Округление до целого |
FXTRACT |
Выделение порядка и мантиссы |
FABS |
Нахождение абсолютной величины |
FCHS |
Изменение знака |
Кроме этого в систему команд FPU входят команды сравнений (табл. 8.4) и трансцендентные команды (табл. 8.5).
Таблица 8.4. Команды сравнений
Мнемоника |
Описание |
FCOM |
Сравнение |
FICOM |
Целочисленное сравнение |
FCOMP |
Сравнение с извлечением из стека |
FICOMP |
Целочисленное сравнение с извлечением из стека |
FCOMPP |
Сравнение и двойное извлечение из стека |
FTST |
Сравнение с нулем |
FXAM |
Анализ |
Таблица 8.5. Трансцендентные команды
Мнемоника |
Описание |
FPTAN |
Частичный тангенс |
FPATAN |
Частичный арктангенс |
FSIN |
Синус |
FCOS |
Косинус |
FSINCOS |
Синус и косинус |
FYL2X |
Вычисление y·log2(x) |
FYL2XP1 |
Вычисление y·log2(x+1) |
F2XM1 |
Вычисление 2x-1 |
Вычислительные устройства, ориентированные на математические расчеты, часто используется стековая организация. Это обусловлено тем, что результат текущей операции часто может заместить один или оба исходных операнда и является операндом следующей команды. Стековая организация позволяет в этих случаях применять так называемые безадресные (нуль-адресные) команды небольшой длины, сокращая число обращений к памяти и, следовательно, повышая быстродействие процессора. Если операция с одним операндом (например, вычисление функций), то она выполняется над вершиной стека с замещением операнда. Если операция двухоперандная, то используется содержимое вершины стека и следующий под ней регистр, результат заменяет оба операнда – высвобождается один регистр стека.
Для программирования ЭВМ с классической стековой архитектурой, например программируемых калькуляторов, часто используется обратная польская запись. При этом сначала в обратном порядке в стек заносятся все операнды, а затем над ними выполняются операции.
Пример. Вычислить один из корней квадратного уравнения с бóльшим значением, если известно, что корни вещественные. То есть для уравнения ax2+bx+c=1 вычислить значение
без проверки выражения под знаком корня.
Используя обратную польскую запись, будем иметь следующую последовательность команд.
Шаг 1. Загрузить а
Шаг 2. Загрузить константу 2
Шаг 3. Умножить (получили в вершине стека 2а)
Шаг 4. Загрузить b (оно будет вычтено из корня)
Шаг 5. Загрузить b
Шаг 6. Возвести в квадрат (получили уменьшаемое)
Шаг 7. Загрузить константу 4
Шаг 8. Загрузить а
Шаг 9. Загрузить с
После этих шагов расположение информации в стеке будет следующим.
-
Вершина стека
с
а
4
b2
b
Дно стека
2а
Шаг 10. Умножить (получили а·с)
Шаг 11. Умножить (получили 4·а·с)
Шаг 12. Вычесть в обратном порядке (получили b2 -4·а·с)
Шаг 13. Вычислить корень квадратный
Шаг 14. Вычесть
Шаг 15. Делить
В итоге в стеке останется одно число – результат.
Система команд FPU позволяет создавать более гибкие и короткие программы из-за возможности использования в операции любого регистра стека или внешней памяти, помещать результат в регистр, где находится второй операнд и так далее.
Один из вариантов программы для FPU с начальными условиями а=3; b=-7; с=2 приведен далее. После выполнения по шагам последней команды в регистре ST(0) получим результат 2.
.MODEL small
.STACK 100h
.DATA
; исходные данные будут загружаться из ОЗУ
a dd 3.0
b dd -7.0
c dd 2.0
x4 dw 4 ; целочисленная константа
.CODE
mov ax,@data
mov ds,ax ; определение сегмента данных
; загрузка стека
fld a
fld b
fld c
; вычисления в стеке
fmul st,st(2) ; c <-- c*a
fimul x4 ; c*a <-- 4*c*a
fld st(1) ; st(0) <-- b
fmul st,st(0) ; b <-- b*b
fsubr ; 4*a*c <-- b*b-4*a*c, b*b пропадает
fsqrt ; корень(b*b-4*a*c)
fsubr ; b <-- корень-b
fxch st(1) ; st(0) <-- а
fadd st,st(0) ; a <-- a+a=2a
fdiv
end
Изменение регистров при выполнении команд этой программы представлено ниже. Отмеченные тэгами как свободные, регистры R0-R3(R4) указаны только в первой таблице.
Команда |
|
Содержимое регистров (выделена вершина стека) |
|
Пояснение |
|
До выполнения |
После выполнения |
||||
fld a fld b fld c
|
R0 |
Не определено |
Не определено |
ST(3) |
|
R1 |
Не определено |
Не определено |
ST(4) |
||
R2 |
Не определено |
Не определено |
ST(5) |
||
R3 |
Не определено |
Не определено |
ST(6) |
||
R4 |
Не определено |
Не определено |
ST(7) |
||
R5 |
Не определено |
c |
ST(0) |
||
R6 |
Не определено |
b |
ST(1) |
||
R7 |
Не определено |
a |
ST(2) |
||
fmul st,st(2) |
c |
a*c |
Извлечения нет (количество занятых регистров сохранилось) |
b |
b |
||
a |
a |
fimul x4 |
a*c |
4*a*c |
Используется целочисленная константа из памяти |
b |
b |
||
a |
a |
fld st(1) |
Не опред. |
b |
Содержимое регистра ST(1) скопировалось в вершину стека и стало ST(2) |
4*a*c |
4*a*c |
||
b |
b |
||
a |
a |
fmul st,st(0) |
b |
b*b |
Возведение в квадрат – умножение на себя |
4*a*c |
4*a*c |
||
b |
b |
||
a |
a |
fsubr |
b*b |
Не опред. |
Стековая команда сокращает количество занятых регистров |
4*a*c |
b*b - 4*a*c |
||
b |
b |
||
a |
a |
fsqrt |
d=b*b-4*a*c |
sqrt(d) |
Извлечение корня квадратного из ST(0) |
b |
b |
||
a |
a |
fsubr |
sqrt(d) |
Не опред. |
Вычитание с освобождением одного регистра |
b |
sqrt(d) - b |
||
a |
a |
fxch st(1) |
Не опред. |
Не опред. |
Теперь в вершине стека работаем со знаменателем |
sqrt(d) - b |
a |
||
a |
sqrt(d) - b |
fadd st,st(0) |
Не опред. |
Не опред. |
Сложение быстрее, чем умножение |
a |
2*a |
||
sqrt(d) - b |
sqrt(d) - b |
fdiv |
Не опред. |
Не опред. |
В стеке осталось одно число – результат |
2*a |
Не опред. |
||
sqrt(d) - b |
(sqrt(d)-b)/(2а) |
Изменение содержимого и взаимного расположения регистров стека легко проследить при отладке программы, используя окно FPU. Оно открывается по команде View -> Numeric Processor. Для перехода в окно View используется комбинация клавиш Alt+v, переключение между окнами – F6, раскрытие окна на все рабочее поле отладчика – F5, повторное нажатие F5 – восстановление размера.
Вид окна при начальной инициализации FPU соответствует изображенному на рис. 8.1.
В левом поле отображаются в 4 столбцах:
значение содержимого тэга: регистр свободен, содержит обычное число, ноль или специальное значение;
относительный адрес регистра без привязки к физическим адресам;
если регистр занят, то указывается его содержимое в арифметическом виде в десятичной системе счисления, то есть число может отображаться и как целое, и как вещественное с фиксированной или плавающей точкой;
реальное содержимое арифметического регистра как пять двухбайтных слов (при прокрутке вправо).
Рис. 8.1. Окно FPU
Значение отмеченного регистра можно изменить, нажав Ctrl+Е, +Z или +C (или правая кнопка мыши): освободить регистр, записать 0, или ввести значение в открывающемся окне как десятичное вещественное, или как целое в 16-ричной системе счисления.
В среднем окне указаны флаги и поля регистра управления, в правом – регистра состояния.
