- •Программирование блока fpu в ia-32. Регистры блока обработки чисел с плавающей точкой
- •Базовые команды математического сопроцессора
- •Административные команды
- •Циклы и ветвления при работе с сопроцессором
- •InCcntr; Инкремент счетчика
- •Программирование сопроцессора с использованием операций вычисления частичных математических функций
Программирование блока fpu в ia-32. Регистры блока обработки чисел с плавающей точкой
В состав блока FPUпроцессоров IA-32 входят восемь регистров данныхR7-R0, регистр теговTW, регистры управленияFPCR(CW–ControlWord) и состоянияFPSR(SW–StatusWord) (рис. 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)
R5
ST(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. Важно отметить, что внутренняя форма представления данных с плавающей точкой в памяти хранится так, что последовательность размещения данных в главной памяти, как и для других форматов данных соответствует принципу – по меньшему адресу записывается менее весомый байт. Так данные в памяти, сформированные по директиве
_longDoubleArgdt23.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
Пример:
_doubleArgdq23.23
Значение константы в шестнадцатеричном представлении имеет вид: 40 37 3а e1 47 ае 14 7b, при загрузке в память байты размещаются в обратном порядке.