- •Программирование блока fpu в ia-32. Регистры блока обработки чисел с плавающей точкой
- •Базовые команды математического сопроцессора
- •Административные команды
- •Циклы и ветвления при работе с сопроцессором
- •Inc cntr ; Инкремент счетчика
- •Программирование сопроцессора с использованием операций вычисления частичных математических функций
Программирование блока fpu в ia-32. Регистры блока обработки чисел с плавающей точкой
В состав блока FPU процессоров IA-32 входят восемь регистров данных R7-R0, регистр тегов TW, регистры управления FPCR (CW – Control Word) и состояния FPSR (SW – Status Word) (рис. 1), а также указатель инструкции FIP, указатель данных (последнего операнда) FDP и код последней FPU-операции FOP.
-
Регистры данных FPU (арифметический стек)
Теги
79
0
1
0
R0
ST(3)
R1
ST(4)
R2
ST(5)
R3
ST(6)
R4
ST(7)
R
5ST(0)
R6
ST(1)
R7
ST(2)
-
15
14
13
11
10
0
TOP=101
SW
CW
TW
Рис. 1. Регистры блока FPU
Регистры данных R7-0 содержат по 80 разрядов, разбитых на три поля: знак, порядок и мантисса, в соответствии с форматом представления чисел с плавающей точкой.
Набор этих регистров организован в виде кольцевого стека, вершина которого определяется содержимым поля ТОР в регистре состояния SW (рис. 2). При выполнении различных операций над содержимым регистров данных расположение вершины стека изменяется.
15 |
14 |
13 |
12 |
11 |
10 |
9 |
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
|
В |
СЗ |
TOP |
C2 |
C1 |
C0 |
ES |
SF |
PE |
UE |
OE |
ZE |
DE |
IE |
SW |
||
x |
x |
x |
x |
RC |
PC |
x |
x |
PM |
UM |
OM |
ZM |
DM |
IM |
CW |
||
tag7 |
tag6 |
tag5 |
tag4 |
tag3 |
tag2 |
tag1 |
tag0 |
TW |
||||||||
Рис. 2. Форматы содержимого регистров SW, CW, TW
Регистр тегов TW содержит 16-разрядное слово, включающее восемь двухбитных тегов tag7-0 (рис. 2). Каждый тег (признак) характеризует содержимое соответствующего регистра данных R7-0, указывая, является ли регистр пустым (незаполненным) или в нем размещается конечное число, нуль или неопределенное значение (например, бесконечность). Значение тега позволяет проверить содержимое регистра, не проводя анализ хранящихся в нем данных. Значения кодов: 00 – допустимое ненулевое число, 01 – нуль, 10 – специальное значений, 11 – незаполненный регистр.
Регистр состояния SW(FPSR) хранит 16-разрядное слово состояния FPU (рис.2), отдельные биты и поля которого имеют следующее назначение:
В признак занятости, включен в состав слова состояния для совместимости с младшими моделями процессоров; значение B дублирует значение ES – общего признака ошибки FPU;
TOP поле, указывающее вершину арифметического стека (рис.1); содержит номер регистра данных FPU, являющегося в данное время верхним в стеке;
С3-С0 признаки результата, значение которых характеризует результат выполнения инструкции FPU; возможные значения кода в разрядах С3-С0 и их воздействие на работу процессора FPU;
ES общий признак ошибки, принимает значение ES=1, если установился хотя бы один из признаков ошибки операции FPU в шести младших разрядах FPSR; одновременно выдается сигнал FERR# = 0 на соответствующий внешний вывод процессора;
SF признак переполнения стека, принимает значение SF=1 при нарушении нормальной работы арифметического стека; используется совместно с признаком С1: если SF=1, то значение С1=1 указывает на выход за верхнюю границу (переполнение) стека, а С1=0 – на выход за нижнюю границу стека.
Младшие шесть разрядов содержимого FPSR хранят признаки ошибок, возникающих при выполнении инструкций FPU:
РЕ признак нарушения точности;
UE признак антипереполнения;
ОЕ признак переполнения;
ZE признак деления на нуль;
DE признак денормализованного операнда;
IE признак неправильной операции.
Регистр управления CW(FPCR) (рис.2) содержит в младшем байте биты РМ, UM, ОМ, ZM, DM, IM, маскирующие соответствующие признаки ошибок, фиксируемых в регистре состояния FPSR. При единичном значении бита маски запрещается прерывание при возникновении соответствующей ошибки FPU. При нулевом значении бита маски установка соответствующего признака ошибки FPU вызывает прерывание процессора.
Старший байт в регистре управления FPSR определяет режим округления и точность представления результатов вычислений:
RC поле управления округлением, определяет выбор одного из методов округления результата операций FPU;
00 – К ближайшему числу (если погрешности округления и в большую, и в меньшую стороны, одинаковы, то округляется к ближайшему четному, т.е. так, чтобы самый младший значащий разряд был нулевым).
01 – К минус-бесконечности
10 – К плюс-бесконечности
11 – К нулю
PC поле управления точностью, задает точность представления результатов арифметических операций FPU: одинарную (23 разряда мантиссы, 8 разрядов порядка), двойную (52 разряда мантиссы, 11 разрядов порядка) или расширенную (64 разряда мантиссы, 15 разрядов порядка).
00 – Одинарная
01 – (не используется)
10 – Двойная
11 – Расширенная
Поле PC учитывается только при выполнении инструкций FADD, FSUB, FDIV, FMUL, FSQRT. Для остальных инструкций FPU используется расширенная точность.
Регистры – указатели инструкции FIP и данных FDP служат для идентификации инструкции, вызвавшей ошибку операции FPU. Содержимое этих регистров зависит от режима работы процессора. В реальном режиме при возникновении ошибки при выполнении инструкции FPU в эти регистры заносятся адрес данной инструкции и адрес использованного операнда. В защищенном режиме в них заносятся селекторы сегментов и относительные адреса инструкции и операнда. Эта информация используется подпрограммой обработки прерываний для выяснения причины ошибки FPU.
FPU хранит код операции последней выполненной инструкции в 11-битовом регистре кода операции (FOP). Здесь хранятся только первый и второй байты кода операции (после всех префиксов), причем первые 5 битов первого байта не хранятся т.к. для FPU операций, они всегда равны 11011B.
Восемь 80-битовых численных регистров с плавающей точкой, скомпонованных в стек, элементы которого обозначаются в языке Ассемблера как (относительный номер регистра) вместе с общей главной памятью и для главного процессора, составляют информационные или запоминающие ресурсы. В большинстве версий Ассемблера номер регистра можно задавать как в обычных, так и в квадратных скобках. Все арифметические данные в сопроцессоре хранятся исключительно в 80-битовом формате, хотя в памяти могут храниться данные еще и в четырех- и восьмибайтном форматах. Внешние форматы данных сопроцессора могут быть целыми и с плавающей точкой: короткие - типа DWORD, длинные - типа QWORD и десятибайтные - типа TBYTE, причем целые данные имеют знак и представляются в дополнительном коде, а в десятибайтном формате они представляются только в двоично-десятичной форме с нулями на месте порядка.
Данные типа, получившего в языке С название long double, которые занимают десять байтов и состоят из знака s, положительной мантиссы m и смещенного порядка с. Порядок определяется по общей формуле для всех типов данных с плавающей точкой с = 2n-1 + р, где п - количество разрядов для представления порядка, р - значение двоичного порядка для представления мантиссы числа с единицей в целой части. Более наглядным может быть определение значения смещения порядка всеми двоичными единицами, кроме старшего разряда. Разрядная сетка числовых регистров сопроцессора имеет параметры п=15, с=16367 и может быть представлена в виде:
s ссссссс |
сссссссс |
m.mm...m |
mmmmmmmm |
||||
79 |
72 |
71 |
64 |
63 |
8 |
7 |
0 |
Регистровый формат для long double
В языке Ассемблера данные такого типа определяются директивой dt. Важно отметить, что внутренняя форма представления данных с плавающей точкой в памяти хранится так, что последовательность размещения данных в главной памяти, как и для других форматов данных соответствует принципу – по меньшему адресу записывается менее весомый байт. Так данные в памяти, сформированные по директиве
_longDoubleArg dt 23.23;
кодируются десятком байтов - 40 03 D9 D7 0А 3D 70 A3 D7 0А, который размещается в памяти в обратной последовательности:
mmmmmmmm |
m.mm...m |
сссссссс |
s ссссссс |
|||||||
7 |
0 |
15 |
8 |
… |
56 |
63 |
71 |
64 |
79 |
72 |
Формат в памяти для long double
Рациональное использование разрядной сетки, заложенное в сопроцессоре обеспечивает возможность не только представлять данные в наиболее широком диапазоне, но и использовать специальные значения данных, сведенные в табл. 1. Такие данные могут возникать вследствие переполнений и антипереполнений или потери значимости результатов операций сопроцессора. Большинство этих значений, за исключением неопределенности и нечисленных данных, могут использоваться в вычислениях вместе с обычными значениями. Так, например, действия с бесконечностью выполняются по правилам вычислений бесконечных пределов. Использование неопределенности и прочих нечисленных значений в вычислениях приводит к формированию неопределенных результатов.
Таблица 1
Тип данных |
Характеристики |
Применение значений |
Денормализованные |
с=0000, m=значение |
Минимальные с плавающей точкой. Специальные с фиксированной точкой |
Ненормализованные |
c=7FFF, m=0.XX...X |
Промежуточные с плавающей точкой |
+0 |
с=0000, s=0, m=0 |
Нулевые данные и результаты |
-0 |
c=0000,s=l,m=0 |
Нулевые результаты |
+00 |
c=7FFF, s=0, m=0 |
Результаты переполнений |
- 00 |
c=7FFF,s=l,m=0 |
Результаты переполнений |
Неопределенность |
c=7FFF,m=1.10...0 |
Результаты особых случаев |
Нечисленные |
c=7FFF,m=l.lX...X |
Специальные данные пользователя |
Ранее в FPU выделялись проективный и афинный режимы обработки специальных значений. В проективном режиме константы +0 и -0, а также + и - не различаются и сравнение числа с бесконечностью приводит к недействительной операции, а в афинном – указанные пары значений различаются и возможны сравнения обычных значений с бесконечностью. Однако, начиная с i486, проективный режим исключен.
Данные типа, называемого в языке C float, а в языке Pascal - Single и занимающего четыре байта и n=8, а с=127 и имеют нормализованное представление с размещением точки, отделяющей целую часть мантиссы от дробной, после старшего двоичного значащего разряда. Единичная-целая часть мантиссы в памяти не записывается:
mmmmmmmm |
mmmmmmmm |
c.mmmmmmm |
s ссссссс |
|||||||
7 |
0 |
15 |
|
|
|
8 |
23 |
16 |
32 |
24 |
Формат в памяти для float
Пример:
_floatArg dd 23.23
Значение константы в шестнадцатиричном представлении имеет вид: 41 b9 d7 0a, при загрузке в память байты размещаются в обратном порядке.
Данные типа double занимают восемь байтов и имеют n=11, с=1023 и представляются в памяти следующим образом:
mmmmmmmm |
mm...mm |
сссс.mmmm |
s ссссссс |
|||||||
7 |
0 |
15 |
8 |
… |
33 |
41 |
55 |
48 |
79 |
72 |
Формат в памяти для double
Пример:
_doubleArg dq 23.23
Значение константы в шестнадцатеричном представлении имеет вид: 40 37 3а e1 47 ае 14 7b, при загрузке в память байты размещаются в обратном порядке.
