x87

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


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

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

Първоначално (до появата на процесора 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. Все пак този набор инструкции остават най-универсални и гъвкави, поради което продължават да се използват широко, особено в случаите, когато точността е по-важна от бързината.

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

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

  • осем 80-битови регистъра за числа с плаваща запетая;
  • три 16-битови контролни регистъра и три регистъра за запазване на състоянието;
  • седем типа данни;
  • над шестдесет инструкции.

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

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

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

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

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

  • Числа с плаваща запетая:
    • Единична точност. Числото заема 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-битово с плваваща запетая с разширена точност и се обработва в този формат.

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

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

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

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

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

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

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

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

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

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

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

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

  • 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 – квадратен корен.

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

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

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

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

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

  • 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 регистровия стек.

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

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

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

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

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

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

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

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

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

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