x87

от Уикипедия, свободната енциклопедия
Направо към: навигация, търсене


x87 е наименование на набор от инструкции за работа с числа с плаваща запетая в процесорната архитектура x86. Подобно на архитектурата x86, тези инструкции носят името си от поредицата математически копроцесори на Intel, които въведоха x87 инструкциите.

История[редактиране | edit source]

Първоначално (до появата на процесора Intel 486), x86 архитектурата не разполага с инструкции за обработка на числа с плаваща запетая. Още от самото начало обаче, Intel предлага математическия копроцесор 8087, който работи съвместно с 8086 и ускорява изчисленията с плаваща запетая.

През 1985, IEEE публикува стандарт за двоична аритметика с плаваща запетая, носещ името IEEE 754. Този стандарт на практика е основан на архитектурата на копроцесора 8087 на Intel и дефинира типовете данни, операциите и начините за обработка на изключенията при работа с двоични числа с плаваща запетая. През 1987 е публикувана по-обща версия на стандарта, която е независима от основата на бройната система и носи името IEEE 854.

Повечето производители на компилатори създават емулиращи програмни библиотеки, които позволяват на програмиста да използва един и същ програмен интерфейс независимо дали компютърът, на който се изпълняват програмите, има математически копроцесор или няма такъв. Това улеснява употребата на инструкциите и те започват да се използват широко в софтуерните продукти. По-ксъно се появяват копроцесорите 80187, 80287, 80387 и 80487. С въвеждането на процесора 486, математическият копроцесор става част от процесорното ядро, а x87 инструкциите стават неразделна част от x86 архитектурата.

След появата на SIMD инструкциите (3DNow!, и най-вече SSE), x87 инструкциите вече не са най-бързият начин за извършване на изчисления с плаваща запетая в един x86 процесор. Все пак, те остават най-универсални и гъвкави, и продължават да се използват широко, особено в случаите, когато точността е по-важна от производителността.

Технология[редактиране | edit source]

Иструкциите за работа с числа с плаваща запетая добавят следните разширения към x86 архитектурата:

  • 8 80-битови регистъра за числа с плаваща запетая.
  • 3 16-битови контролни регистъра и 3 регистъра за запазване на състоянието.
  • 7 типа данни.
  • Над 60 инструкции.

Регистри[редактиране | edit source]

x87 инструкциите използват 8 регистъра за данни с имена ST0 - ST7. Всеки от тях е 80-битов и съдържа едно 80-битово число с плаваща запетая с разширена точност (виж Типове данни). Освен тези регистри, x87 включва и 3 16-битови контролни регистъра (наричани control, status и tag регистри); както и 3 други регистъра, които се използват за записване на адреса на инструкцията, данните и вида на операцията, които са предизвикали последното x87 програмно изключение (exception).

Осемте регистъра за данни са организирани в стек, като за указател на върха на стека се използлва 3-битово поле от 16-битовия status регистър.

Типове данни[редактиране | edit source]

x87 инструкциите работят върху 7 типа данни, които могат да се разделят на следните групи:

  • Числа с плаваща запетая:
    • Единична точност. Числото заема 32 бита, като мантисата е 24-битова, а експонентата - 8-битова. Обхватът на тези числа е от 1,18 * 10–38 до 3,40 * 1038 (при нормализирано представяне - т.е. когато няма водещи нули в мантисата и точността е максимална).
    • Двойна точност. Числото заема 64 бита, като мантисата е 53-битова, а експонентата - 11-битова. Обхватът на тези числа е от 2,23 * 10–308 до 1,79 * 10308 (при нормализирано представяне).
    • Разширена точност. Числото заема 80 бита, като мантисата е 64-битова, а експонентата - 16-битова. Обхватът на тези числа е от 3,37 * 10–4932 до 1,18 * 104932 (при нормализирано представяне).
  • Цели числа:
    • Word. Заема 16 бита и има обхват от –32768 до 32767.
    • Short. Заема 32 бита и има обхват от –231 to 231 – 1.
    • Long. Заема 64 бита и има обхват от –263 to 263 – 1
  • Пакетирани двоично-десетични (BCD) цели числа:
    • 80-битово BCD число. Числото се състои от 18 десетични цифри и има обхват от –1018 + 1 до 1018 – 1.

Трябва да се има предвид, че гореописаните формати на данните важат само при съхраняването на числата в паметта. При прехвърлянето на числото в някои от x87 регистрите, то автоматично се преобразува в 80-битово число с плваваща запетая с разширена точност и се обработва в този формат.

Методи за адресиране[редактиране | edit source]

Операндите на x87 инструкциите може да се намират или в x87 регистрите, или в паметта (не се използват непосредствени операнди - такива, които са кодирани в самата инструкция).

Повечето x87 инструкции могат да приемат операнд от паметта, а някои от тях могат и да записват резултата в паметта. При достъп до операнд в паметта, могат да се използват стандартните x86 методи за адресиране.

Повечето x87 инструкции могат да приемат операнд от x87 регистър и да записват резултата в него. При достъп до x87 регистрите се използва означението ST(i), където i е число от 0 до 7. ST(0) обозначава регистъра, който е на върха на регистровия стек, ST(1) е регистърът под него и т.н.

Повечето x87 инструкции са с два операнда, като първият е едновременно и място, където се записва резултатът от операцията (подобно на x86 инструкциите).

Инструкции[редактиране | edit source]

Имената на всички x87 инструкции започват с буквата F (например FADD, FMUL и др.). Те могат да се разделят на следните групи:

Трансфер и конвертиране на данни[редактиране | edit source]

  • FLD, FST, FSTP - прехвърляне на число с плаваща запетая от и към върха на регистровия стек.
  • FILD, FIST, FISTP - прехвърляне на цяло число от и към върха на регистровия стек.
  • FBLD, FBSTP - прехвърляне на BCD число от и към върха на регистровия стек.
  • FCMOVB, FCMOVBE, FCMOVE, FCMOVNB, FCMOVNBE, FCMOVNE, FCMOVNU, FCMOVU - условно прехвърляне в рамките на регистровия стек в зависимост от флагове в x86 регистъра FLAGS.
  • FXCH - размяна на съдържанието на върха на регистровия стек и друг регистър от стека.
  • FXTRACT - извлича мантисата и експонентата на числото от върха на регистровия стек.

Зареждане на константи[редактиране | edit source]

  • FLDZ - зареждане на числото 0 на върха на регистровия стек.
  • FLD1 - зареждане на числото 1 на върха на регистровия стек.
  • FLDPI - зареждане на числото π (Пи) на върха на регистровия стек.
  • FLDL2E - зареждане на log2 e на върха на регистровия стек.
  • FLDL2T - зареждане на log2 10 на върха на регистровия стек.
  • FLDLG2 - зареждане на log10 2 на върха на регистровия стек.
  • FLDLN2 - зареждане на ln 2 (loge 2) на върха на регистровия стек.

Аритметични[редактиране | edit source]

  • FADD, FADDP, FIADD - събиране на две числа с плаваща запетая. FADD записва резултата на върха на регистровия стек. FADDP записва резултата в ST(1) и прави този регистър новия връх на регистровия стек. FIADD е еквивалент на FADD с тази разлика, че единият операнд е цяло число от паметта.
  • FSUB, FSUBP, FISUB, FSUBR, FSUBRP, FISUBR - изваждане на числа с плаваща запетая. FSUB записва резултата на върха на регистровия стек. FSUBP записва резултата в ST(1) и прави този регистър новия връх на регистровия стек. FISUB е еквивалент на FSUB с тази разлика, че единият операнд е цяло число от паметта. Инструкциите със суфикс R са еквивалентни на първите три инструкции, но с разменени места на операндите (тъй като изваждането не е комутативна операция).
  • FMUL, FMULP, FIMUL - умножение на две числа с плаваща запетая. FMUL записва резултата на върха на регистровия стек. FMULP записва резултата в ST(1) и прави този регистър новия връх на регистровия стек. FIMUL е еквивалент на FMUL с тази разлика, че единия операнд е цяло число от паметта.
  • FDIV, FDIVP, FIDIV, FDIVR, FDIVRP, FIDIVR - деление на числа с плаваща запетая. FDIV записва резултата на върха на регистровия стек. FDIVP записва резултата в ST(1) и прави този регистър новия връх на регистровия стек. FIDIV е еквивалент на FDIV с тази разлика, че единият операнд е цяло число от паметта. Инструкциите със суфикс R са еквивалентни на първите три инструкции, но с разменени места на операндите (тъй като делението не е комутативна операция).
  • FABS - абсолютна стойност.
  • FCHS - смяна на знака.
  • FRNDINT - закръгляване на число с плаваща запетая до цяло число.
  • FPREM, FPREM1 - частичен остатък при делене на числа с плаваща запетая.
  • FSQRT - квадратен корен.

Трансцендентни[редактиране | edit source]

  • FSIN, FCOS, FSINCOS, FTAN, FATAN - изчисляване съответно на синус, косинус, синус и косинус, тангенс и арктангенс от число с плаваща запетая.
  • F2XM1 - изчислява 2x - 1.
  • FSCALE - изчислява 2x.
  • FYL2X - изчислява y * log2 x.
  • FYL2XP1 - изчислява y * log2 (x + 1).

Сравнение и проверка[редактиране | edit source]

  • FCOM, FCOMP, FCOMPP, FCOMI, FCOMIP - сравнение на операнди с плаваща запетая.
  • FUCOM, FUCOMP, FUCOMPP, FUCOMI, FUCOMIP - сравнение на операнди с плаваща запетая, при което операдите може да са безкрайности.
  • FICOM, FICOMP - сравнение на целочислен операнд с върха на стека.
  • FTST - сравнение на операнд с плаваща запетая с 0.
  • FXAM - проверка за специални стойности на операнда с плаваща запетая.

Други[редактиране | edit source]

  • FDECSTP - намалява указателя на регистровия стек с 1.
  • FINCSTP - увеличава указателя на регистровия стек с 1.
  • FFREE - обявява даден x87 регистър за празен.
  • FNOP - празна инструкция.
  • FINIT, FNINIT - инициализиране на x87 блока на процесора.
  • FWAIT - проверка за x87 изключения.
  • FCLEX, FNCLEX - нулиране на флаговете на status регистъра.
  • FLDCW, FSTCW, FNSTCW - зареждане и записване на control регистъра.
  • FSTSW, FNSTSW - записване на status регистъра.
  • FLDENV, FNSTENV, FSTENV - зареждане от и записване в паметта на състоянието на x87 блока на процесора без x87 регистровия стек.
  • FSAVE, FNSAVE, FRSTOR - записване в паметта и зареждане от паметта на цялостното състояние на x87 блока на процесора, включително и x87 регистровия стек.

Проблеми[редактиране | edit source]

По отношение на функционалност, точност и универсалност, x87 инструкциите са напълно достатъчни за почти всички видове приложения. Основният им недостатък се крие в наследената от x86 SISD организация, при която всяка инструкция оперира само върху един набор от операнди. Това значително намалява максимално възможната производителност и ограничава употребата на x87 инструкциите в области като обработка на звук и видео, компютърни игри и други.

Приложения[редактиране | edit source]

В исторически аспект, x87 са основният набор от инструкции за обработка на числа с плаваща запетая. Значението им е най-голямо по време на появата на първите 3D компютърни игри (Doom, Quake) и възпроизвеждането на видео на персоналните компютри.

След появата на SSE, x87 инструкциите се използват в много по-тесен кръг от приложения, при които са по-важни точността и възможността за гъвкава обработка на грешките и специалните случаи (най-вече научно-технически приложения).

Специфичните предимства на x87 инструкциите са:

  • Представяне на числата в съответстиве със стандартите IEEE 754 и IEEE 854, което осигурява повтаряемост на резултатите на всички платформи, които поддържат тези стандарти.
  • От архитектурна гледна точка, x87 блоковете на повечето съвременни процесори са независими от тези на SSE инструкциите, което позволява по-висока теоретична производителност, ако се използват едновременно x87 и SSE инструкции.
  • По-разнообразни инструкции и много гъвкав механизъм за обработка на безкрайности и изключения.

Виж също[редактиране | edit source]

  • SSE - популярно разширение на x86 инструкциите, което позволява SIMD обработка на числа с плаваща запетая.
  • 3DNow! - друго SIMD разширение на x86 инструкциите.
  • MMX - целочислени SIMD разширения на x86 инструкциите.

Външни препратки[редактиране | edit source]