36
правок
Изменения
Новая страница: «'''Floating-point unit''', FPU — блок процессора предназначенный для обратки чисел с плавающей точ...»
'''Floating-point unit''', FPU — блок процессора предназначенный для обратки чисел с плавающей точкой.
Раньше сопроцессор был отдельной микросхемой. Теперь чаще всего он находится непосредственно на кристале процессора.
=Типы данных=
Сопроцессор архитектуры х86 способен обрабатывать следующие типы данных:
* single (float)
* double
* extended (80 бит)
* int (16/32/64 бит)
* bcd80 — двоично-десятичный 10-байтовый формат, каждый полубайт которого хранит одну десятичную цифру
=Регистры=
Регистры общего назначения не подходят для обработки чисел с плавающей точкой. Для этих чисел существуют 8 специальных регистров организованных в кольцевой стек.
Это 80-байтовые регистры r0-r7, однако в программе к ним обращаются по именам st(*).
{| border="3"
|st(2)
|r7
|-
|st(1)
|r6
|-
|st(0)
|r5
|-
|st(7)
|r4
|-
|st(6)
|r3
|-
|st(5)
|r2
|-
|st(4)
|r1
|-
|st(3)
|r0
|}
При добавлении в стек еще однго элемента произойдет сдвиг этих имен. st(7) станет st(0) — вершиной стека.
{| border="3"
|st(3)
|r7
|-
|st(2)
|r6
|-
|st(1)
|r5
|-
|st(0)
|r4
|-
|st(7)
|r3
|-
|st(6)
|r2
|-
|st(5)
|r1
|-
|st(4)
|r0
|}
==Управляющие регистры==
Так же существуют несколько специальных регистров:
* cr \\управляющий регистр. Позволяет контролировать режимы округления и пр.
* sr \\регистр состония
* tw \\метки (пустой, число, не число, ...)
При обработке исключений так же используются:
*fip \\регистр указателя команд
*fdp \\регистр указателя данных
=Команды=
* fld/fild/fbl
загрузка из памяти или копирование из другого fpu регистра в st(0). Например:
fld st(0)
fild dword [eax]
* fst(p)/fist(p)/fbstp *(p) +выталкивает вершину
загрузка в память или st(*) из st(0) регистра
* fxch \\swap(st(0), st(*))
* fcmov_cc \\условная загрузка
* fcom st(2)(p(p)) \\сравнение с вершиной
* fstsw ax
* sahf
флаги сопроцессора в флаги процессора
* fucom(p) \\еще одно сравнение
* ficom(p) \\сравнение с памятью
* fcomi(p) \\результат сравнения в flags
* fucomi(p)
==Вычисления==
* fadd(p)/fiadd \\st(0) = arg + st(0)
* fsub(p)/fisub \\st(0) = st(0) - arg
* sfubr(p)/fisubr \\st(0) = arg - st(0)
* fmul(p)/fimul
* fdiv(p)/fidiv
* dfivr(p)/fidivr
* frem/frem1 st(0) - n * st(1) \\остаток получаемый вычитаниями (не блолее 64 штук)
* fchs
изменить знак на противоположный.
Работают с st(0) Не нуждаются в отдельныз пояснениях.
* fabs
* frndint
* fsin
* fcos
* fsincos
* fptan
* fpatanb
*fld1/z/pi/...
загрузка констант
*fincstp
*fdecstp
двигаем указатель стека, не меняя состояние регистров (пустой/полный)
*ffree
озвободить регистр
*fnop
поделать ничего. Теперь и на fpu.
Раньше сопроцессор был отдельной микросхемой. Теперь чаще всего он находится непосредственно на кристале процессора.
=Типы данных=
Сопроцессор архитектуры х86 способен обрабатывать следующие типы данных:
* single (float)
* double
* extended (80 бит)
* int (16/32/64 бит)
* bcd80 — двоично-десятичный 10-байтовый формат, каждый полубайт которого хранит одну десятичную цифру
=Регистры=
Регистры общего назначения не подходят для обработки чисел с плавающей точкой. Для этих чисел существуют 8 специальных регистров организованных в кольцевой стек.
Это 80-байтовые регистры r0-r7, однако в программе к ним обращаются по именам st(*).
{| border="3"
|st(2)
|r7
|-
|st(1)
|r6
|-
|st(0)
|r5
|-
|st(7)
|r4
|-
|st(6)
|r3
|-
|st(5)
|r2
|-
|st(4)
|r1
|-
|st(3)
|r0
|}
При добавлении в стек еще однго элемента произойдет сдвиг этих имен. st(7) станет st(0) — вершиной стека.
{| border="3"
|st(3)
|r7
|-
|st(2)
|r6
|-
|st(1)
|r5
|-
|st(0)
|r4
|-
|st(7)
|r3
|-
|st(6)
|r2
|-
|st(5)
|r1
|-
|st(4)
|r0
|}
==Управляющие регистры==
Так же существуют несколько специальных регистров:
* cr \\управляющий регистр. Позволяет контролировать режимы округления и пр.
* sr \\регистр состония
* tw \\метки (пустой, число, не число, ...)
При обработке исключений так же используются:
*fip \\регистр указателя команд
*fdp \\регистр указателя данных
=Команды=
* fld/fild/fbl
загрузка из памяти или копирование из другого fpu регистра в st(0). Например:
fld st(0)
fild dword [eax]
* fst(p)/fist(p)/fbstp *(p) +выталкивает вершину
загрузка в память или st(*) из st(0) регистра
* fxch \\swap(st(0), st(*))
* fcmov_cc \\условная загрузка
* fcom st(2)(p(p)) \\сравнение с вершиной
* fstsw ax
* sahf
флаги сопроцессора в флаги процессора
* fucom(p) \\еще одно сравнение
* ficom(p) \\сравнение с памятью
* fcomi(p) \\результат сравнения в flags
* fucomi(p)
==Вычисления==
* fadd(p)/fiadd \\st(0) = arg + st(0)
* fsub(p)/fisub \\st(0) = st(0) - arg
* sfubr(p)/fisubr \\st(0) = arg - st(0)
* fmul(p)/fimul
* fdiv(p)/fidiv
* dfivr(p)/fidivr
* frem/frem1 st(0) - n * st(1) \\остаток получаемый вычитаниями (не блолее 64 штук)
* fchs
изменить знак на противоположный.
Работают с st(0) Не нуждаются в отдельныз пояснениях.
* fabs
* frndint
* fsin
* fcos
* fsincos
* fptan
* fpatanb
*fld1/z/pi/...
загрузка констант
*fincstp
*fdecstp
двигаем указатель стека, не меняя состояние регистров (пустой/полный)
*ffree
озвободить регистр
*fnop
поделать ничего. Теперь и на fpu.