X87
от Уикипедия, свободната енциклопедия
- Правилното заглавие на тази статия е x87. Първата буква е изобразена като главна поради технически ограничения.
x87 е наименование на набор от инструкции за работа с числа с плаваща запетая в процесорната архитектура x86. Подобно на архитектурата x86, тези инструкции носят името си от поредицата математически копроцесори на Intel, които въведоха x87 инструкциите.
Съдържание |
[редактиране] История
Първоначално (до появата на процесора 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 архитектурата:
- 8 80-битови регистъра за числа с плаваща запетая.
- 3 16-битови контролни регистъра и 3 регистъра за запазване на състоянието.
- 7 типа данни.
- Над 60 инструкции.
[редактиране] Регистри
x87 инструкциите използват 8 регистъра за данни с имена ST0 - ST7. Всеки от тях е 80-битов и съдържа едно 80-битово число с плаваща запетая с разширена точност (виж Типове данни). Освен тези регистри, x87 включва и 3 16-битови контролни регистъра (наричани control, status и tag регистри); както и 3 други регистъра, които се използват за записване на адреса на инструкцията, данните и вида на операцията, които са предизвикали последното x87 програмно изключение (exception).
Осемте регистъра за данни са организирани в стек, като за указател на върха на стека се използлва 3-битово поле от 16-битовия status регистър.
[редактиране] Типове данни
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-битово число с плваваща запетая с разширена точност и се обработва в този формат.
[редактиране] Методи за адресиране
Операндите на 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.0 на върха на регистровия стек.
- FLD1 - зареждане на числото 1.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, FNINT - инициализиране на 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 инструкциите.
[редактиране] Външни връзки
- Ръководство за софтуерния разработчик за архитектурата IA-32, том 1 (PDF), виж глава 7 за x87 програмиране (на английски език)