Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
прогр.docx
Скачиваний:
23
Добавлен:
21.12.2018
Размер:
2.58 Mб
Скачать

Лекция №6. Работа с сопроцессором. Команды для работы с fpu. Работа с fpu.

Вещественные форматы, используемые в процессорах Intel:

  • короткое вещественное (Single): бит 31 — знак мантиссы, биты 30 –23 — 8-битный порядок + 127 (27-1), биты 22–0 — 23-битная мантисса без первой цифры;

  • длинное вещественное (Double): бит 63 — знак мантиссы, биты 62–52 — 11-битный порядок + 1023 (210-1), биты 51 – 0 — 52-битная мантисса без первой цифры;

  • расширенное вещественное (Extended): бит 79 — знак мантиссы, биты 78–64 — 15-битный порядок + 16 383 (214-1), биты 63–0 — 64-битная мантисса с первой цифрой (то есть бит 63 равен 1).

Регистры FPU

FPU предоставляет восемь регистров для хранения данных и пять вспомогательных регистров.

Регистры данных (R0 – R7) рассматриваются как стек, вершина которого называется ST(0), а более глубокие элементы — ST(1), ST(2) и так далее до ST(7).

Рис. 13. Регистры FPU

К регистрам R0 – R7 нельзя обращаться напрямую, по именам, но если процессор поддерживает расширение ММХ, то мантиссы, находящиеся в этих регистрах, становятся доступны, как ММ0 – ММ7.

Регистр состояний SR содержит слово состояния FPU:

Регистр управления CR:

Биты 15 – 13 — зарезервированы.

Бит 12 «IC» — управление бесконечностью (поддерживается для совместимости с 8087 и 80287 — вне зависимости от значения этого бита > ).

Биты 11 – 10 «RC» — управление округлением.

Биты 9 – 8 «PC» — управление точностью.

Биты 7 – 6 — зарезервированы.

Бит 5 «РМ» — маска неточного результата.

Бит 4 «UM» — маска антипереполнения.

Бит 3 «ОМ» — маска переполнения.

Бит 2 «ZM» — маска деления на ноль.

Бит 1 «DM» — маска денормализованного операнда.

Бит 0 «IM» — маска недействительной операции.

Биты RC определяют способ округления результатов команд FPU до заданной точности (табл. 10).

Таблица 10. Способы округления

Значение RC

Способ округления

00

к ближайшему числу

01

к отрицательной бесконечности

10

к положительной бесконечности

11

к нулю

Биты PC определяют точность результатов команд FADD, FSUB, FSUBR, FMUL, FDIV, FDIVR и FSQRT (табл. 11).

Таблица 11. Точность результатов

Значение PC

Точность результатов

00

одинарная точность (32-битные числа)

01

Зарезервировано

10

двойная точность (64-битные числа)

11

расширенная точность (80-битные числа)

Регистр тегов TW содержит восемь пар бит, описывающих содержание каждого регистра данных.

Регистры FIP и FDP содержат адрес последней выполненной команды (кроме FINIT, FCLEX, FLDCW, FSTCW, FSTSW, FSTSWAX, FSTENV, FLDENV, FSAVE, FRSTOR и FWAIT) и адрес ее операнда соответственно и используются в обработчиках исключений для анализа вызвавшей его команды.

Команды пересылки данных FPU

1)

 Команда:

FLD источник

 Назначение:

Загрузить вещественное число в стек

Команда помещает в стек содержимое источника (32-, 64- или 80-битная переменная или ST(n)). Команда FLD ST(0) делает копию вершины стека.

2)

 Команда:

FST приемник

 Назначение:

Скопировать вещественное число из стека

 Команда:

FSTP приемник

 Назначение:

Считать вещественное число из стека

Копирует ST(0) в приемник (32- или 64-битную переменную или пустой ST(n) в случае FST; 32-, 64- или 80-битную переменную или пустой ST(n) в случае FSTP). FSTP после этого выталкивает число из стека (помечает ST(0) как пустой).

3)

 Команда:

FILD источник

 Назначение:

Загрузить целое число в стек

Преобразовывает целое число со знаком из источника (16-, 32- или 64-битная переменная) в вещественный формат и помещает в вершину стека.

4)

 Команда:

FIST приемник

 Назначение:

Скопировать целое число из стека

 Команда:

FISTP приемник

 Назначение:

Считать целое число из стека

Преобразовывает число из вершины стека в целое со знаком и записывает его в приемник (16- или 32-битная переменная для FIST; 16-, 32- или 64-битная переменная для FISTP). FISTP после этого выталкивает число из стека (помечает ST(0) как пустой).

5)

 Команда:

FXCH приемник

 Назначение:

Обменять местами два регистра стека

Обмен местами содержимого регистра ST(0) и приёмника (регистр ST(n)). Если операнд не указан, обменивается содержимое ST(0) и ST(1).

Базовая арифметика FPU

Сопроцессор использует шесть основных типов арифметических команд:

Fxxx

Используются ST(1) и ST(0). Первый операнд берется из верхушки стека (источник), второй - следующий элемент стека. Результат выполнения команды записывается в стек.

Fxxx память

Источник берется из памяти, приемником является верхушка стека ST(0). Указатель стека ST не изменяется, команда действительна только для операндов с одинарной и двойной точностью.

FIxxx память

Аналогично предыдущему типу команды, но операндами могут быть 16- или 32-битовые целые числа.

пр, ист.

Fxxx ST, ST(i)

Для этого типа регистр ST(i) является источником, а ST(0) - верхушка стека - приемником. Указатель стека не изменяется.

Fxxx ST(i), ST

Для этого типа регитр ST(0) является источником, а ST(i) - приемником. Указатель стека не изменяется.

FxxxP ST(i), ST

Регистр ST(i) - приемник, регистр ST(0) - источник. После выполнения команды источник ST(0) извлекается из стека.

Строка "xxx" может принимать следующие значения:

ADD Сложение

SUB Вычитание

SUBR Обратное вычитание, уменьшаемое и вычитаемое

меняются местами

MUL Умножение

DIV Деление

DIVR Обратное деление, делимое и делитель меняются местами

1)

 Команда:

FADD приемник,источник

 Назначение:

Сложение вещественных чисел

 Команда:

FADDP приемник,источник

 Назначение:

Сложение вещественных чисел с выталкиванием из стека

 Команда:

FIADD источник

 Назначение:

Сложение целых чисел

Команда выполняет сложение источника и приемника и помещает результат в приемник. Команда FADDP после этого выталкивает ST(0) из стека (помечает ST(0) как пустой и увеличивает ТОР на один). Команды сложения могут принимать следующие формы:

  • FADD источник, когда источником является 32- или 64-битная переменная, а приемником — ST(0);

  • FADD ST(0),ST(n), FADD ST(n),ST(0), FADDP ST(n),ST(0), когда источник и приемник заданы явно в виде регистров FPU;

  • FADD без операндов — эквивалентно FADD ST(0),ST(1); FADDP без операндов — эквивалентно FADDP ST(1),ST(0);

  • FIADD источник, когда источником является 16- или 32-битная переменная, содержащая целое число, а приемником — ST(0).

2)

 Команда:

FSUB приемник,источник

 Назначение:

Вычитание вещественных чисел

 Команда:

FSUBP приемник,источник

 Назначение:

Вычитание с выталкиванием из стека

 Команда:

FISUB источник

 Назначение:

Вычитание целых чисел

Выполняет вычитание источника из приемника и сохраняет результат в приемнике. Команда FSUBP после этого выталкивает ST(0) из стека (помечает ST(0) как пустой и увеличивает ТОР на один). Команды вычитания могут принимать следующие формы:

  • FSUB источник, когда источником является 32- или 64-битная переменная, содержащая вещественное число, а приемником — ST(0);

  • FSUB ST(0),ST(n), FSUB ST(n),ST(0), FSUBP ST(n),ST(0), когда источник и приемник заданы явно в виде регистров FPU;

  • FSUB без операндов — эквивалентно FSUB ST(0),ST(1); FSUBP без операндов — эквивалентно FSUBP ST(1),ST(0);

  • FISUB источник, когда источником является 16- или 32-битная переменная, содержащая целое число, а приемником — ST(0).

Если один из операндов — бесконечность, результат — бесконечность соответствующего знака. Если оба операнда — бесконечности одного знака, результат не определен (происходит исключение «недопустимая операция»).

3)

 Команда:

FSUBR приемник,источник

 Назначение:

Обратное вычитание вещественных чисел

 Команда:

FSUBRP приемник,источник

 Назначение:

Обратное вычитание с выталкиванием

 Команда:

FISUBR источник

 Назначение:

Обратное вычитание целых чисел

Команды эквивалентны FSUB/FSUBP/FISUB , но выполняют вычитание приемника из источника, а не источника из приемника.

4)

 Команда:

FMUL приемник,источник

 Назначение:

Умножение вещественных чисел

 Команда:

FMULP приемник,источник

 Назначение:

Умножение с выталкиванием из стека

 Команда:

FIMUL источник

 Назначение:

Умножение целых чисел

Выполняет умножение источника и приемника и помещает результат в приемник. Команда FMULP после этого выталкивает ST(0) из стека (помечает ST(0) как пустой и увеличивает ТОР на один). Команды умножения могут принимать следующие формы:

  • FMUL источник, когда источником является 32- или 64-битная переменная, а приемником — ST(0);

  • FMUL ST(0),ST(n), FMUL ST(n),ST(0), FMULP ST(n),ST(0), когда источник и приемник заданы явно в виде регистров FPU;

  • FMUL без операндов — эквивалентно FMUL ST(0),ST(1); FMULP без операндов — эквивалентно FMULP ST(1),ST(0);

  • FIMUL источник, когда источником является 16- или 32-битная переменная, содержащая целое число, а приемником — ST(0).

5)

 Команда:

FDIV приемник,источник

 Назначение:

Деление вещественных чисел

 Команда:

FDIVP приемник,источник

 Назначение:

Деление с выталкиванием из стека

 Команда:

FIDIV источник

 Назначение:

Деление целых чисел

Выполняет деление приемника на источник и сохраняет результат в приемнике. Команда FDIVP после этого выталкивает ST(0) из стека (помечает ST(0) как пустой и увеличивает ТОР на один). Команды могут принимать следующие формы:

  • FDIV источник, когда источником является 32- или 64-битная переменная, содержащая вещественное число, а приемником — ST(0);

  • FDIV ST(0),ST(n), FDIV ST(n),ST(0), FDIVP ST(n),ST(0), когда источник и приемник заданы явно в виде регистров FPU;

  • FDIV без операндов — эквивалентно FDIV ST(0),ST(1); FDIVP без операндов — эквивалентно FDIVP ST(1),ST(0);

  • FIDIV источник, когда источником является 16- или 32-битная переменная, содержащая целое число, а приемником — ST(0).

6)

 Команда:

FCHS

 Назначение:

Изменить знак

Изменяет знак ST(0), превращая положительное число в отрицательное, и наоборот.

7)

 Команда:

FRNDINT

 Назначение:

Округлить до целого

Округляет значение ST(0) до целого числа в соответствии с режимом округления, заданным битами RC.

8)

 Команда:

FSCALE

 Назначение:

Масштабировать по степеням двойки

Умножает ST(0) на два в степени ST(1) и записывает результат в ST(0). Выполняет вычисление:

ST(0)= ST(0)*2ST(1).

Значение ST(1) предварительно округляется в сторону нуля до целого числа.

9)

 Команда:

F2XM1

 Назначение:

Вычисление 2x-1

Команда F2XM1 возводит 2 в степень X, но только если X меньше или равен 1/2, то есть команда возводит 2 в степень, равную ST(0), и вычитает 1. Результат сохраняется в ST(0). Значение ST(0) должно лежать в пределах от -0,5 до 0.5, иначе результат не определен.

ST(0)=2ST(0) -1; -0,5<ST(0)<0,5

29,97=29+0,97/2+0,97/2 =29 *20,97/2 *20,97/2

10)

 Команда:

FYL2X

 Назначение:

Вычисление y*log2(x);

ST(1) = ST(1)*log2(ST(0)), верхний элемент выталкивается из стека.

Константы FPU

 Команда:

FLD1

 Назначение:

Поместить в стек 1,0

 Команда:

FLDZ

 Назначение:

Поместить в стек +0,0

 Команда:

FLDPI

 Назначение:

Поместить в стек число

 Команда:

FLDL2E

 Назначение:

Поместить в стек log2(e)

 Команда:

FLDL2T

 Назначение:

Поместить в стек log2(10)

Команды управления FPU

 Команда:

FSTCW приемник

 Назначение:

Сохранить регистр CR

 Команда:

FNSTCW приемник

 Назначение:

Сохранить регистр CR без ожидания

Команды копируют содержимое CR в приемник (16-битная переменяя). Команда FSTCW, в отличие от FNSTCW, проверяет наличие произошедших и необработанных исключений и обрабатывает их до выполнения.

 Команда:

FLDCW источник

 Назначение:

Загрузить регистр CR

 Процессор:

8087

Копирует содержимое источника (16-битная переменная) в регистр CR.

Пример 3: Сложить два числа (В+С), используя сопроцессор. (real2.asm)

.386

.model flat, stdcall

includelib import32.lib

extrn ExitProcess:PROC

extrn MessageBoxA:PROC

.data

Ttl db "Arifmeticheskoe viragenie",0h

Msg db 10 dup(' '),0h

db 0h

B DW 10

C DW 3

Y dd ?

.code

start:

finit

FILD B

FILD C

FADD

fist Y

mov eax,Y

xor edi,edi

xor esi,esi

mov si,10

mov edi,9

lp2: xor edx,edx

div esi

xchg eax,edx

add al,'0'

mov byte ptr [Msg+edi],al

xchg eax,edx

dec edi

or eax,eax

jne lp2

push 0h

push offset Ttl

push offset Msg

push 0h

call MessageBoxA

push 0h

call ExitProcess

end start

Пример 4. Вычислить 10х =y, x=3. (real4.asm)

1)

2) Величину log210 – можно задать как константу с помощью команды FLDL2T.

3) Команда F2XM1 возводит 2 в степень X, но только если X меньше или равен 1/2, то есть команда возводит 2 в степень, равную ST(0), и вычитает 1. Результат сохраняется в ST(0). Значение ST(0) должно лежать в пределах от -0,5 до 0.5, иначе результат не определен.

4) Команда FSCALE умножает ST(0) на два в степени ST(1) и записывает результат в ST(0). Значение ST(1) предварительно округляется в сторону нуля до целого числа.

5) если х=3, то:

.386

.model flat, stdcall

includelib import32.lib

extrn ExitProcess:PROC

extrn MessageBoxA:PROC

.data

Ttl db "Arifmeticheskoe viragenie",0h

Msg db 10 dup(' '),0h

db 0h

X Dd 3

Y dd ?

OLD_CW DW ?

NEW_CW DW ?

.code

start:

finit

FILD X ; загрузить степень в стек ST(0)

FLDL2T ;загрузить константу log2(10) в ST(0)

FMULP ST(1),ST(0) ; умножение с выталкиванием из стека 3*log210=9.965784284662087

FNSTCW OLD_CW ; сохранить регистр CR без ожидания

FWAIT ; ожидание готовности FPU

MOV AX,OLD_CW ; значения регистра управления сохраняем в АХ

AND AX,NOT 0C00H ; ax not 0000 1100 0000 0000=>ax and 1111 0011 1111 1111

OR AX,0400H ; ax or 0000 0100 0000 0000

MOV NEW_CW,AX

FLDCW NEW_CW ; загрузить регистр CR из NEW_CW

FLD1 ; загрузить вещественное число 1,0 в стек

FCHS ; изменяет знак ST(0), превращая положительное число в

; отрицательное, и наоборот.

FLD ST(1) ; загрузить вещественное число (x*log2(10)) в стек

FRNDINT ; Округляет значение ST(0) до целого числа в соответствии с

; режимом округления, заданным битами RC.

; INT(9.965784284662087)=9

FLDCW OLD_CW ; Загрузить регистр CR из OLD_CW

FXCH ST(2) ; Обмен местами содержимого регистра ST(0) и

; источника ST(2) . Если операнд не указан,

; обменивается содержимое ST(0) и ST(1).

FSUB ST(0),ST(2) ; Вычитание вещественных чисел 9,965784285-9=0.965784285

FSCALE ; умножает содержимое ST(0) на 2 в степени,

; содержащейся в ST(1)= -1.

; (1/2=2**(-1))=>0.965784284662087/2

F2XM1 ; возводит 2 в степень, равную ST(0), и вычитает 1.

; Результат сохраняется в ST(0). Значение ST(0) должно

; лежать в пределах от -0,5 до +0,5, иначе результат не

; определен.

FSUBRP ST(1),ST(0) ; выполняют вычитание приемника из источника, а не

; источника из приемника.=>0.39754248593736856+1

FMUL ST(0),ST(0) ; умножение источника ST(0) на приёмник ST(0);

; 2**(0.482892142)*2**(0.482892142)

FSCALE ; Умножает ST(0) на два в степени ST(1) и записывает

; результат в ST(0).

FIST Y

mov eax,Y

xor edi,edi

xor esi,esi

mov si,10

mov edi,9

lp2: xor edx,edx

div esi

xchg eax,edx

add al,'0'

mov byte ptr [Msg+edi],al

xchg eax,edx

dec edi

or eax,eax

jne lp2

push 0h

push offset Ttl

push offset Msg

push 0h

call MessageBoxA

push 0h

call ExitProcess

end start

Блок-схема подсчета выражения: y=10x

Инициализируется сопроцессор.

Загружаем степень X в стек ST(0): FILD X

Загружаем константу Е=log2(10) в ST(0): FLDL2T

Умножаем константу Е на степень: FMULP ST(1),ST(0)

Сохраняем значение регистра CR для указания способа округления при вычислениях.

Сохраняем значение регистра CR для указания способа округления при вычислениях. Настраиваем регистр CR так, чтобы округления производились к ближайшему числу.

FNSTCW OLD_CW

FWAIT

MOV AX,OLD_CW

AND AX,NOT 0C00H

OR AX,0400H

MOV NEW_CW,AX

FLDCW NEW_CW

Вычитаем из степени х*log2(10) целую часть степени для получения дробной части:

FSUB ST(0),ST(2) ; 9.965784284662087-9=0,965784284662087=Р

Делим Р на 2, для того, чтобы воспользоваться командой F2XM1, так как Р>0.5:

FSCALE; ST(0)=Р*2-1=P/2

Для получения результата 2Р/2 отнимаем от ST(0) минус единицу, которая находится в регистре ST(1). Результат в ST(0):

FSUBRP ST(1),ST(0) ; ST(0)=P/2

Умножаем 2Р/2 *2Р/2.=:

FMUL ST(0),ST(0)

Возводим 2 в степень Р/2 для:

F2XM1 ;

Умножаем *29. ST(1)=9:

FSCALE

Записываем полученный результат в переменную Y. Выводим значение переменной Y на экран с помощью функции MessageBoxA.

Выделяем из степени x*log210 целую часть:

FLD ST(1)

FRNDINT

П