Система команд x86 |
|
Программирование - Архитектура и система команд микропроцессоров x86 |
FDIV
Влияние команды на флаги и форматы команды:
* |
* |
* |
* |
* |
* |
* |
D8 /6 |
FDIV m32real |
ST(0) = ST(0) / m32real |
8087 |
fdiv dword ptr [si] |
DC /6 |
FDIV m64real |
ST(0) = ST(0) / m64real |
8087 |
fdiv qword ptr [bx] |
D8 F0+i |
FDIV ST,ST(i) |
ST(0) = ST(0) / ST(i) |
8087 |
fdiv ST,ST(4) |
DC F8+i |
FDIV ST(i),ST |
ST(i) = ST(i) / ST(0) |
8087 |
fdiv ST(2),ST |
DE F8+i |
FDIVP ST(i),ST |
ST(i) = ST(i) / ST(0), верхний элемент выталкивается из регистрового стека |
8087 |
fdivp ST(3),ST |
DE F9 |
FDIVP |
ST(1) = ST(1) / ST(0), верхний элемент выталкивается из регистрового стека |
8087 |
fdivp |
DE /6 |
FIDIV m16int |
ST(0) = ST(0) / m16int |
8087 |
fidiv word ptr memo |
DA /6 |
FIDIV m32int |
ST(0) = ST(0) / m32int |
8087 |
fidiv dword ptr [si] |
Описание:
Команды деления FDIV, FDIVP, FIDIV делят операнд-назначение на операнд-источник (в однооперандных формах команд деления в качестве операнда-назначения используется ST) и возвращают частное на место операнда-назначения. Команда FDIVP, кроме этого, выталкивает из регистрового стека FPU верхний элемент (ST). Если в мнемонике команды FDIVP не записано никакого операнда, то ST(1) делится на ST.
Если операнд-источник находится в памяти, то он может быть в представлен форматах: короткого вещественного, длинного вещественного, целого слова или короткого целого, перед выполнением операции он автоматически приводится к временному вещественному формату.
Флаги C0, C2, C3 регистра SW после выполнения команды деления неопределены, флаг C1 устанавливается равным 0 в случае возникновения стековой ошибки #IS, а также указывает направление округления в случае возникновения исключения #P (неточный результат) (C1 = 0 – округление к меньшему, C1 = 1 – округление к большему).
Если операция деления вызывает исключение #Z (деление на нуль) и соответствующий бит маски сброшен (генерация прерывания разрешена), то результат операции в операнде-назначении не сохраняется. Если исключение #Z имеет место при установленном бите маски (генерация прерывания запрещена), то в операнд-назначение возвращается бесконечность со знаком, равным ИСКЛЮЧАЮЩЕМУ ИЛИ знаков операндов.
В таблице 6.148. приведены возвращаемые командами деления значения для различных классов операндов, а также случаи, когда возникают исключения #IA и #Z.
Таблица 6.148. Значения, возвращаемые командами FDIV, FDIVP, FIDIV
для различных классов операндов
SRCDEST |
-INF |
-F |
-0 |
+0 |
+F |
+INF |
NaN |
-INF |
#IA |
+0 |
+0 |
-0 |
-0 |
#IA |
NaN |
-F |
+INF |
+F |
+0 |
-0 |
-F |
-INF |
NaN |
-I |
+INF |
+F |
+0 |
-0 |
-F |
-INF |
NaN |
-0 |
+INF |
#Z |
#IA |
#IA |
#Z |
-INF |
NaN |
+0 |
-INF |
#Z |
#IA |
#IA |
#Z |
+INF |
NaN |
+I |
-INF |
-F |
-0 |
+0 |
+F |
+INF |
NaN |
+F |
-INF |
-F |
-0 |
+0 |
+F |
+INF |
NaN |
+INF |
#IA |
-0 |
-0 |
+0 |
+0 |
#IA |
NaN |
NaN |
NaN |
NaN |
NaN |
NaN |
NaN |
NaN |
NaN |
|
|
|
|
|
|
|
|
I - Конечное целое значение |
|
|
|
|
|
||
F - Конечное вещественное значение |
|
|
|
|
Исключение #IA возникает также, если любой из операндов SNaN или представлен в неподдерживаемом формате.
Операция:
IF SRC = 0
THEN
#Z;
ELSE
IF Команда FIDIV
THEN
DEST = DEST / ConvertExtendedReal(SRC);
ELSE (* Операнд-источник представлен в вещественном формате *)
DEST = DEST / SRC;
FI;
FI;
IF Команда FDIVP
THEN
PopRegisterStack;
FI;
Особые ситуации защищенного режима:
#GP(0), если используется некорректный эффективный адрес операнда в памяти в сегментах CS, DS, ES, FS, GS или нулевой селектор.
#SS(0) при использовании некорректного эффективного адреса в сегменте SS.
#NM, если CR0.EM = 1 или CR0.TS = 1.
#PF(Код ошибки) при страничной ошибке.
#AC(0) при невыровненной ссылке в память при текущем уровне привилегий равном 3.
Особые ситуации режима реальной адресации:
#GP, если любая часть операнда находится вне пространства эффективных адресов в сегментах CS, DS, ES, FS или GS.
#SS, если любая часть операнда находится вне пространства эффективных адресов в сегменте SS.
#NM, если CR0.EM = 1 или CR0.TS = 1.
Особые ситуации режима V86:
Такие же, как и в режиме реальной адресации.
#PF(Код ошибки) при страничной ошибке.
#AC(0) при невыровненной ссылке в память.
Замечание:
В процессорах, поддерживающих стандарт IEEE-754 (Intel387, Intel486, …) операция деления с использованием денормализованных операндов при определенных условиях может вызвать исключение #U (антипереполнение). Аналогичная ситуация на математических сопроцессорах Intel287 и 8087, не отвечающих стандарту IEEE-754, приводит к исключению #IA.
Некоторые ассемблеры поддерживают для безоперандной версии команды FDIVP мнемонику FDIV. Т.е. безоперандная мнемоника всегда вызывает выталкивание из стека верхнего элемента.
Ошибка Pentium FDIV
В процессорах Pentium для ускорения выполнения операций деления был использован так называемый SRT-алгоритм (получил свое название по фамилиям авторов – Sweeney, Robertson, Tochen). Несмотря на уже имевшуюся практику применения (впервые такой вычислитель был реализован в компьютерах IBM System 360/91), специалисты Intel пропустили ошибку во внутренних таблицах, используемых при вычислении результата операции. Эта ошибка в отдельных случаях приводит к неточности возвращаемого результата в операциях деления, выполняемых командами FDIV, FDIVP, FDIVR, FDIVRP, FIDIV, FIDIVR, FPREM, FPREM1. Наглядно воспроизвести ошибку позволяет операция:
- $( 4195835.0/3145727.0 = 1.333820449136241002 $) (правильное значение);
- $( 4195835.0/3145727.0 = 1.333739068902037589 $) (ошибочное значение, возвращаемое процессором, содержащим дефект).
Ошибка затрагивает не только операции деления. Некоторые функции используют деление внутри своего микрокода в процессе вычислений. Таким образом подвержены ошибке оказались также команды FPTAN и FPATAN. Воспроизвести ошибку позволяют операции:
- $( tan(0,8549592142878324) = 1,149782816566037 $) (правильное значение);
- $( tan(0,8549592142878324) = 1,149782816388642 $) (ошибочное значение, возвращаемое процессором, содержащим дефект).
- $( atan(0,9333324451392881) = 0,7509285877097011 $) (правильное значение);
- $( atan(0,9333324451392881) = 0,7509285896965135 $) (ошибочное значение, возвращаемое процессором, содержащим дефект).
Ошибка была выявлена в октябре 1994 года и успела попасть в очень большое количество выпущенных на рынок приборов. Ее значение и влияние были столь велики, что производители компиляторов даже вынуждены были реализовать специальные решения, позволявшие детектировать и обходить данную ошибку на этапе компиляции (заменяя выполнение ошибочных команд соответствующим программным кодом без их использования).
Подробнее об ошибке Pentium FDIV смотрите здесь.
Все права защищены © Алексей Ровдо, 1994-2023. Перепечатка возможна только по согласованию с владельцем авторских прав. admin@club155.ru