Skip to content

lecture_6

chrislvt edited this page Jun 21, 2020 · 10 revisions

Содержание

  1. История
  2. Сопроцессор
  3. Форма представления чисел с плавающей запятой в FPU
  4. Особые числа в FPU
  5. Регистры FPU
  6. Исключения FPU
  7. Команды пересылки данных FPU
  8. Базовая арифметика FPU
  9. Команды сравнения FPU
  10. Трансцендентные операции FPU
  11. Константы FPU
  12. Команды управления FPU
  13. Команда SPUID (С 80486)
  14. Вторая половина лекции тоже расписана, просто не сделано содержание. Надо сделать

История

Математический сопроцессор изначально шел в качестве отдельной микросхемы. Позже, в конце 80-ых и начале 90-ых, с 80496DX его интегрировали на одну плату с основным процессором.

Дальше стали появляться дополнительные расширения процессоров (которые могут в процессоре либо быть, либо не быть). В разных процессорах расширения могут быть реализованы по-разному.

Сопроцессор (FPU - Floating Point Unit)

Математический сопроцессор умеет манипулировать различными типами данных. Ему доступно:

  1. Три целых типа:
  • Целое слово (16 бит)
  • Короткое целое (32 бита)
  • Длинное слово (64 бита)
  1. Отдельный тип, упакованный в 10ый:
  • Упакованное десятичное (80 бит)
  1. Три вещественных типа:
  • Короткое вещественное (32 бита)
  • Длинное вещественное (64 бита)
  • Расширенное вещественное (80 бит)

Форма представления чисел с плавающей запятой в FPU

Основная задача математического сопроцессора - обработка уже не целых чисел, а чисел более сложного формата, дробей. Дроби представляются в компьютере в наиболее общем виде - в виде чисел с плавающей запятой. Число с плавающей запятой состоит из мантиссы (значащих чисел) и из экспоненты (степени, на которую мантисса умножается).

Особенности при представлении вещественных чисел в сопроцессорах 8087 и дальше такие, что экспонента хранится в беззнаковом виде, то есть она увеличена на определенную константу в зависимости от типа числа (чтобы экспонента всегда была положительной). Это позволяет легко и складывать, и сравнивать экспоненты без каких-то диапазонных разрывов.

Нормализованная форма преставления числа - это такая форма представления числа, когда оно представлено в виде между единицей и двумя. То есть когда мы число перевели в дробную форму и домножили его на степень двойки так чтобы запятая располагалась после самого первого двоичного разряда. (с) Кузнецов

Пример представления такой дроби

0.5 + 0.125 = 0.625

1/2 + 1.8 = 0,101b

Для нормализации мы сдвигаем запятую вправо и запоминаем, что экспонента должна быть равна -1:

1,01b * 2^-1

В 32-разрядном формате - формате короткого вещественного числа получается, что:

  1. Старший бит - знак числа (знак мантиссы), хотя в любом формате старший бит отвечает за знак.
  2. 8 битов - экспонента. В данном примере она увеличивается на 127, соответственно 127 - 1.
  3. 23 бита - мантисса, записанная без первой единицы. Так как число в нормализованном виде всегда начинается с единицы, эту единицу можно отбросить и дополнительно емкость мантиссы повысить на 1 разряд.

Все вычисления FPU выполняются в расширенном 80-битном формате. То есть, для вычисления, все числа, независимо от текущего формата числа, переводятся в 80-разрядный.

Особые числа FPU

Сопроцессор поддерживает несколько так называемых особых значений чисел:

  1. Положительная бесконечность: знаковый - 0, мантисса - нули, экспонента - единицы.
  2. Отрицательная бесконечность: знаковый - 1, мантисса - нули, экспонента - единицы
  3. NaN (Not a Number)
  • Тихое значение qNan - не приводит к исключению, может возникать при приведении типов/отдельных сравнениях, когда как таковой арифметической ошибки нет, но в результате число получить невозможно.
  • Сигнальный тип sNan - приводит к исключению, может возникать при переполнении в большую/меньшую сторону (при делении на ноль) и прочих ошибочных ситуациях.
  1. Денормализованные числа - такие, которые не укладываются в заданный формат представления числа (в заданный тип данных из трёх доступных вещественных форматов сопроцессора) и позволяют хранить еще меньшие числа. Для этого в экспоненту заносятся нули, а мантисса считается умноженной на 2 в отрицательной степени, которая еще меньше чем минимальное значение экспоненты.

То есть они автомати аппаратно при обработке чисел ... ааа чет тут кузнецов сказал? Их обработка может производиться дольше чем обработка нормализованных чисел. Они нужны для повышения точности чтобы не потерять значения вблизи нуля

Бесконечное значение возникает при делении бесконечности на ноль.

Регистры FPU

В сопроцессоре предусмотрено восемь 80-разрядных регистров R0..R7. По отдельности к ним доступа нет, адресация при выполнении операций происходит в виде стека ST, который реализован внутри сопроцессора. ST соответствует регистру - текущей вершине стека, ST(1)..ST(7) - прочие регистры, которые находятся ниже вершины.

Для выполнения операций в качестве одного из операндов берется регистр, на который указывает вершина стека. Вершина стека автоматически каждый раз увеличивается. Когда указатель вершины доходит до восьмого регистра - самого высокого регистра, автоматически происходит сброс в ноль (стек как бы закольцован). После 8 регистра снова вершиной становится первый регистр, и так далее.

Так же в FPU имеются следующие регистры:

  • SR - регистр состояний. Отдельные биты описывают по отдельности состояния регистров, и в целом сигнализируют о различных ошибках, переполнениях и так далее.
  • CR - регистр управления. Через него можно настраивать правила округления чисел и контроль точности. Можно с помощью специальных битов указывать, как будет производиться округление - в большую сторону, в меньшую сторону, по математическим правилам или нет. Настройки для округления чисел с плавающей запятой достаточно гибкие.
  • TW - 8 пар битов, описывающих состояния восьми регистров в стеке: число, ноль, не-число, пусто. изначально все регистры пустые, инициализированные 1
  • FIP, FDP - адрес последней выполненной команды и её операнда, во время работы которых произошло исключение.

SR, CR и TW содержат в себе 16 разрядов (слово). Разрядность регистров FIP и FDP зависит от разрядности машины, так как адреса могут иметь разную длину.

Исключения FPU

  • Неточный результат - произошло округление по правилам, заданным в CR. Бит в SR хранит направление округления. Это исключение происходит регулярно.
  • Антипереполнение - переход в денормализованное число. В отличие от переполнения, получилось слишком маленькое число.
  • Переполнение - переход в "бесконечность" соответствующего знака. Разрядов не хватило, получилось слишком большое число. В результате получается бесконечность соответствующего знака.
  • Деление на ноль - переход в "бесконечность" соответствующего знака.
  • Денормализованный операнд. Это скорее такая особенность сопроссора: вещественный тип данных сам по себе обработку денормализованных чисел не предусматривает.
  • Недействительная операция

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

Команд в математическом сопроцессоре едва ли не больше, чем в основном процессоре. Неспроста он сначала шел отдельной микросхемой.

  • FLD - загрузить вещественное число из источника (переменная или ST(n)) в стек. Номер вершины в SR увеличивается
  • FST/FSTP - скопировать/считать число с вершины стека в приёмик
  • FILD - преобразовать целое число из источника в вещественное и загрузить в стек
  • FIST/FISTP - преобразовать вершину в целое и скопировать/считать в приёмник
  • FBLD, FBSTP - загрузить/считать десятичное BCD-число
  • FXCH - обменять местами два регистра (вершину и источник) стека

ну короче я устала писать потом допишу

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

Есть аналоги вычитания деления обратных команд, когда делится второй аргумент на первый. При поиске остатка от деления используется последовательное вычитание, если вышли за 64 вычитания, то выставляется специальный флаг того, что нашли только частичный остаток от деления.

  • FADD, FADDP, FIADD - сложение, сложение с выталкиванием из стека, сложение целых. Один из операндов - вершина стека
  • FSUB, FSUBP, FISUB - вычитание
  • FSUBR, FSUBRP, FISUBR - обратное вычитание (приёмника из источника)
  • FMUL, FMULP, FIMUL - умножение
  • FDIV, FDIVP, FIDIV - деление
  • FDIVR, FDIVRP, FIDIVR - обратное деление (источника на приёмник)
  • FPREM - найти частичный остаток от деления (делится ST(0) на ST(1)). Остаток ищется цепочкой вычитаний, до 64 раз
  • FABS - взять модуль числа
  • FCHS - изменить знак
  • FRNDINT - округлить до целого
  • FSCALE - масштабировать по степеням двойки (ST(0) умножается на 2ST(1))
  • FXTRACT - извлечь мантиссу и экспоненту. ST(0) разделяется на мантиссу и экспоненту, мантисса дописывается на вершину стека
  • FSQRT - вычисляет квадратный корень ST(0)

Команды сравнения FPU

По результатам команд сопроцессора могут выставляться как основные флаги процессора, так еще и дополнительные в регистре sr (тоже предусмотрено 4 разряда, которые соответствую флагам результатов выполнения сопроцессора).

FCOMP и FCOMPP выталкивают или одно или сразу два числа с вершины стека прим. сравниваем два числа на вершине стека между собой то можем их там оставить, а можем их извлечь и регистр стека освободить

  • FCOM, FCOMP, FCOMPP - сравнить и вытолкнуть из стека
  • FUCOM, FUCOMP, FUCOMPP - сравнить без учёта порядков и вытолкнуть
  • FICOM, FICOMP, FICOMP - сравнить целые
  • FCOMI, FCOMIP, FUCOMI, FUCOMIP (P6) были не сразу, а добавлены уже в pentium
  • FTST - сравнивает с нулём
  • FXAM - выставляет флаги в соответствии с типом числа

Трансцендентные операции FPU

К подобным операциям относится вычисление синуса, косинуса, и синуса и косинуса(FSINCOS кладет и синус и косинус на вершину стека). Операндом должно выступать значение в радаинах, при том, не во всем диапазоне(нельзя давать слишком большие углы)

FSIN

  • FCOS
  • FSINCOS
  • FPTAN
  • FPATAN
  • F2XM1 – 2x-1
  • FYL2X, FYL2XP1 – y * log2x, y * log2(x+1)

Константы FPU

Загрузка на вершину стека констант

  • FLD1 – 1,0
  • FLDZ - +0,0
  • FLDPI - число Пи
  • FLDL2E - log2e
  • FLDL2T - log210
  • FLDLN2 – ln(2)
  • FLDLG2 – lg(2)

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

Предусмотрены команды прямого изменения указателя вершины стека, сохранения/изменения состояния сопроцессора. По-хорошему, FINIT должна вызываться первой, при желании поработать с сопроцессором (она очистит все регистры от данных, просто пометит их пустыми, регистры cr и sr значениями по умолчанию). FSAVE и FRSTOR сохраняют 94 или 108 байт в зависимости от разрядности машины.

В FSTSW было написано сохранения регистра CR, сказал, что опечатка

  • FINCSTP, FDECSTP - увеличить/уменьшить указатель вершины стека
  • FFREE - освободить регистр
  • FINIT, FNINIT - инициализировать сопроцессор / инициализировать без ожидания (очистка данных, инициализация CR и SR по умолчанию)
  • FCLEX, FNCLEX - обнулить флаги исключений / обнулить без ожидания
  • FSTCW, FNSTCW - сохранить CR в переменную / сохранить без ожидания
  • FLDCW - загрузить CR
  • FSTENV, FNSTENV – сохранить вспомогательные регистры (14/28 байт) / сохранить без ожидания
  • FLDENV - загрузить вспомогательные регистры
  • FSAVE, FNSAVE, FXSAVE - сохранить состояние (94/108 байт) и инициализировать, аналогично FINIT
  • FRSTOR, FXRSTOR - восстановить состояние FPU
  • FSTSW, FNSTSW - сохранение SR
  • WAIT, FWAIT - обработка исключений
  • FNOP - отсутствие операции

Команда CPUID (с 80496)

Идентификация процессора. CPUID сообщает информацию о производителе, типе и модификации процессора и о наличии различных расширений. Её параметром является регистр EAX.

  1. Если EAX = 0, то в качестве результата возвращается следующее:
  • EAX - максимальное допустимое значение (1 или 2)
  • EBX:ECX:EDX – 12-байтный идентификатор производителя процессора (ASCII-строка).
  1. Если EAX = 1, то:
  • EAX - версия процессора (модификация, модель, семейство).
  • EDX - 32-разрядная информация о доступных расширениях:
    • наличие FPU (есть ли он)
    • поддержка режима V86 (который используется в 32-разрядных ОС для нативного запуска DOS-приложений)
    • поддержка точек останова (тех аппаратных защищенного режима из прошлой лекции)
    • CR4 - это дополнительный управляющий регистр
    • расширение адресации PAE
    • APIC
    • быстрые системные вызовы
    • PGE
    • машинно-специфичный регистр
    • команды условной пересылки данных CMOVcc
    • MMX
    • FXSR (MMX2)
    • SSE
  1. Если EAX = 2, то в EAX, EBX, ECX, EDX возвращается информация о существующих механизмов кэширования и поддержке TLB.

MMX (1997, PentiumMMX)

MMX - расширение, встроенное для увеличение эффективности обработки больших потоков данных (изображения, звук, видео...) - выполнение простых операций над массивами однотипных чисел.

Это расширение делает доступным 8 64-битных регистров MM0..MM7. На самом деле эти не самостоятельные регистры - мантиссы регистров FPU. При записи чего-то в MM0..ММ7, экспонента и знаковый бит регистров сопроцессора заполняются единицами.

Пользоваться одновременно и FPU, и MMX не получится, требуется каждый раз при переключением между ними FSAVE+FRSTOR, чтобы сохранять состояние MMX.

Типы данных MMX. Можно в 8байтные 64-раз загрузить что-то и интерпретировать это что то как байт, 4 слова, 2 двойных слово или целиком одно большое учетверенное слово

  • учетверённое слово (64 бита)

  • упакованные двойные слова (2)

  • упакованные слова (4)

  • упакованные байты (8).

Команды MMX перемещают упакованные данные в память или обычные регистры целиком, но арифметические и логические операции выполняют поэлементно.

В командах MMX введено понятие насыщение. Переполнение не приводит к полному сбросу значения, а просто переводит к сохранению максимального значения. Насыщение - замена переполнения/антипереполнения превращением в максимальное/минимальное значение. Это нужно, например, самый простой случай, при обработке картинки. Если мы из черного цвета будет что то вычитать, мы получим черный, и внезапно белый цвет не получим.

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

MOVD, MOVQ - пересылка двойных/учетверённых слов из регистров MMX и обратно.

PACKSSWB, PACKSSDW - упаковка со знаковым насыщением слов в байты/двойных слов в слова.

Приёмник -> младшая половина приёмника, источник -> старшая половина приёмника, таким образом старшие половины источника и приемника просто отбрасываются. В случае наличия значащих разрядов происходит насыщение и достижение максимального знакового значения - максимальное отрицательное или максимальное положительное.

PACKUSWB - упаковка слов в байты с беззнаковым насыщением.

PUNPCKHBW, PUNPCKHWD, PUNPCKHDQ - распаковка и объединение старших элементов источника и приёмника через 1

Арифметические операции MMX

  • PADDB, PADDW, PADDD -поэлементное сложение, перенос игнорируется
  • PADDSB, PADDSW -сложение с насыщением
  • PADDSB, PADDSW -сложение с насыщением
  • PADDUSB, PADDUSW -беззнаковое сложение с насыщением
  • PSUBB, PSUBW, PDUBD -вычитание, заём игнорируется
  • PSUBSB, PSUBSW -вычитание с насыщением
  • PSUBUSB, PSUBUSW -беззнаковое вычитание с насыщением
  • PMILHW, PMULLW -старшее/младшее умножение (сохраняет старшую или младшую части результата в приёмник)
  • PMADDWD - умножение и сложение. Перемножает 4 слова, затем попарно складывает произведения двух старших и двух младших

Команды сравнения MMX

Поэлементые, для сравнения байтов, слов, двойных слов.

  • PCMPEQB, PCMPEQW, PCMPEQD -проверка на равенство. Если пара равна -соответствующий элемент приёмника заполняется единицами, иначе -нулями
  • PCMPGTB, PCMPGTW, PCMPGTD -сравнение. Если элемент приёмника больше, то заполняется единицами, иначе - нулями

Логические операции MMX

Работают просто побитово.

  • PAND -логическое И
  • PANDN -логическое НЕ-И (штрих Шеффера) (источник*НЕ(приёмник))
  • POR -логическое ИЛИ
  • PXOR -исключающее ИЛИ

Сдвиговые операции MMX

  • PSLLW, PSLLD, PSLLQ - логический влево
  • PSRLW, PSRLD, PSRLQ -логический вправо
  • PSRAW, PSRAD -арифметический вправо
Clone this wiki locally