- •Программирование блока fpu в ia-32. Регистры блока обработки чисел с плавающей точкой
- •Базовые команды математического сопроцессора
- •Административные команды
- •Циклы и ветвления при работе с сопроцессором
- •Inc cntr ; Инкремент счетчика
- •Программирование сопроцессора с использованием операций вычисления частичных математических функций
Циклы и ветвления при работе с сопроцессором
Простейшая организация циклов при работе с сопроцессором и известном количестве повторений состоит в использовании для организации циклов исключительно команд центрального процессора с использованием механизмов, рассмотренных в предыдущих главах.
Для организации ветвлений и проверки условий окончания циклов используются группа команд сравнения сопроцессора и команды передачи слова состояния в центральный процессор. FCOM – сравнивает st[0] с операндом, а FICOM – с целым операндом из памяти; FCOMP - сравнивает содержимое st[0] с операндом, после чего исключает его из стека сопроцессора, a FICOMP делает то же действие при сравнении с целочисленным операндом; FCOMPP - сравнивает два верхних регистра стека st[0] и st[1] с последующим их исключением из стека.
FTST – сравнивает st[0] с 0. Перечисленные команды меняют содержимое регистра состояния в соответствии с результатом вычитания второго операнда из первого и могут быть использованы для организации условной передачи управления по арифметическим отношениям.
Результат |
С3 |
С2 |
С0 |
ST[0] > X |
0 |
0 |
0 |
ST[0] < X |
0 |
0 |
1 |
ST[0] = X |
1 |
0 |
0 |
Не сравнимы |
1 |
1 |
1 |
Коды результата операции сравнения в регистре SW
С учетом особенностей структуры регистра FLAGS ЦП и регистра состояния математического сопроцессора, а также наличием команды сопроцессора FSTSW wrd и центрального процессора. SAHF можно организовать передачу флагов сопроцессора в ЦП.
|
Регистр
управления FPU
15
14
13
12
11
10
9
8
7
.
.
.
0
C3
C2
C1
C0
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
И |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
SW FPU
FLAGS
C0
CF
C1
---
C2
PF
C3
ZF |
Регистр AX
(AH,AL)
15
14
13
12
11
10
9
8
7
.
.
.
0
C3
C2
C1
C0
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Р
15
.
.
.
8
7
6
5
4
3
2
1
0
ZF
PF
1
CF
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Перемещение кодов условий из регистра управления FPU в регистр флагов CPU.
В старших моделях IA-32 реализована группа команд сравнения FCOMI и FCOMIP, которые, выполняют сравнение аналогично командам FCOM и FCOMI, но устанавливают флаги не в FPSR, а прямо в регистре EFLAGS центрального процессора.
Результат |
ZF |
PF |
CF |
ST[0] > X |
0 |
0 |
0 |
ST[0] < X |
0 |
0 |
1 |
ST[0] = X |
1 |
0 |
0 |
Не сравнимы |
1 |
1 |
1 |
Коды результата операции сравнения в регистре EFLAGS
Таким образом полностью соблюдается соответствие: C0CF, C2PF и C3ZF.
При программировании условных переходов по результатам работы сопроцессора нужно учитывать, что в режиме эмуляции команды транслируются в модифицированную форму, в которой сохраняется изоморфность к сопроцессорной программе по количеству байтов, а значит и размещению команд, а также сохраняются биты, в которых определены операции сопроцессора. При этом код операции WAIT заменяется на INT с указателем определенной группы уровней прерываний. На листинге эти преобразования не отображаются. Для построения унифицированной программы, пригодной для выполнения на сопроцессоре, и в режиме эмуляции необходимо использовать команду FWAIT вместо WAIT.
Условные переходы по результатам сравнений в сопроцессоре можно организовать макроопределением следующего вида:
FJ MACRO cd,lb ; Прототип макровызова
FSTSW stsw ; Запись в память регистра состояния
;FPU и команды центрального процессора
FWAIT ; Ожидание окончания пересылки
MOV ah,byte ptr stsw+1 ;Копирование регистра состояния
SAHF ; Сохранение содержимого регистра ah
; в регистре флагов
J&CD lb ; Условный переход
ENDM
Для программирования условного перехода по результату сравнения программисту достаточно использовать макровызов вида:
[метка:] FJ условие_перехода, метка_перехода
Первый операнд макрокоманды, определяет условие перехода теми же буквами, которые используются в командах условных переходов по результатам беззнаковой арифметики, то есть а – больше, b – меньше, n – отрицание и e – равенство. Команда FXAM позволяет получить гораздо больше информации о содержимом st[0], но дает особое кодирование битов признака результатов, и может использоваться также для инициализации кодов условия.
Содержимое st[0] |
С3 |
С2 |
С0 |
Поддерживаемый формат |
0 |
0 |
0 |
Не-число |
0 |
0 |
1 |
Нормализованное число |
0 |
1 |
0 |
Бесконечность |
0 |
1 |
1 |
Ноль |
1 |
0 |
0 |
Пусто |
1 |
0 |
1 |
Денормализованное число |
1 |
1 |
0 |
Коды результата анализа содержимого регистра st[0], командой FXAMP.
Таким образом, синхронизация параллельной работы центрального процессора и математического сопроцессора реализуется достаточно просто и в большинстве случаев прозрачно для программиста. Другой случай необходимости синхронизации связан с возникновением особых ситуаций в сопроцессоре. Сопроцессор при незамаскированной особой ситуации формирует сигнал прерывания к центральному процессору по одному из трех номеров векторов прерываний 07h - при отсутствии сопроцессора и 10h или 75h - при ошибках и особых случаях в сопроцессоре, в зависимости от структуры аппаратной части.
Для рационального программирования вычислений по формулам разложения в ряд и рекурсивным формулам следует придерживаться следующих рекомендаций по построению программ. После того как четко определена предметная область, ее форматы данных и цели составляемых программ в виде явных аналитических выражений, необходимо выполнить предварительные эквивалентные аналитические преобразования, сокращающие, а в пределе и исключающие выполнение повторных вычислений в программе. Эти действия по своему существу обеспечивают машинно-независимую оптимизацию программ. После этого для получения рациональной программы необходимо выполнить эффективное распределение запоминающих и операционных ресурсов, в случае языка Ассемблера семантически совпадающих с ресурсами центрального процессора и математического сопроцессора.
Для рационального использования запоминающих и операционных ресурсов вычислительной системы необходимо соблюдать следующие принципы:
минимизация числа пересылок, для чего данные целесообразно размещать в хранилище, используемом при выполнении требуемых операций;
при большом объеме промежуточных вычислении предпочтением для сохранения в регистрах пользуются повторно используемые данные, а при недостатке регистров, редко используемые данные предпочтительнее сохранять в памяти.
При программировании вычисления математических функций могут применяться два подхода: вычисления по приближенным итеративным формулам, использующим элементарные математические операции, и вычисления, основанные на специальных операциях сопроцессора, вычисляющих частичные значения трансцендентных функций.
В качестве базового примера рассмотрим процесс составления программы в соответствии с формулой разложения в ряд Маклорена. При прямой реализации формулы вычисления ряда в процессоре, имеющем операции сложения и умножения, источником избыточных вычислений являются многократные умножения при вычислении степеней х. Простейший способ их устранения основан на аналитическом определении отношения последующего и предыдущего членов ряда.
Построим пример реализации программы для экспоненциальной функции еx, вычисляемой по формуле:
|
, где 0! = 1. В этом случае отношение (i+1)-го члена ряда ai+1 к i-му аi имеет вид: R = аi+1/аi = х/i. |
С точки зрения распределения регистров сопроцессора при циклическом выполнении вычислений в верхушке стека целесообразно хранить значение очередного члена ряда, так как оно может использоваться для накопления суммы в регистре из глубины стека и для их обновления путем умножения на отношение членов ряда R. Процедура вычисления функции экспоненты, составленная с учетом соглашений о связях языка C, может быть представлена в виде:
_Ехр PROC
PUSH BP ;Стандартное сохранение базового указателя стека
MOV BP,SP ;Установка нового значения базового указателя
FLD QWORD PTR[BP+4] ; Загрузка начального значения
; суммы х
FLD st ; Загрузка значения 0-го члена ряда
FLD st ; Загрузка х для вычисления постоянного
; множителя
MOV cntr,1 ; Запись начального значения счетчика
LSi:FMUL st[1] ; Домножение на - х*x
FIMUL cntr ; Домножение на 2i-1

нструкция
FSTSW
Инструкция SAF
егистр
FLAGS