Направо към съдържанието

x86

от Уикипедия, свободната енциклопедия


x86 се нарича общата микроархитектура на фамилия микропроцесори, основана на Intel 8086. Първите процесори от тази фамилия, разработени и произвеждани от Intel, са обозначавани с номера, завършващи на 86: 8086, 80186, 80286, 80386 (впоследствие i386) и 486 (i486). Водена от маркетингови съображения и ограничена от невъзможността да защити търговска марка върху число, Intel решава да именува следващите процесори от тази фамилия с имена: Pentium, Core. В крайна сметка, името x86 остава като име на цялата фамилия.

Архитектурата на два пъти е била разширявана към по-голям размер на машинната дума. Първите процесори от тази фамилия са 16-битови. През 1985 г. Intel пуска 32-битовия процесор Intel 386. Обикновено обозначението x86 се използва за 32-битовата архитектура, като освен него се използва и IA-32 (на английски: Intel Architecture 32-bit). През 2003 г. AMD пусна на пазара процесора Athlon 64, който разшири архитектурата до 64 бита. 64-битовата x86 архитектура се обозначава с x86-64, като освен него се използват и други обозначения: AMD64 (от AMD), EM64T или IA-32e (от Intel) и x64 (от Microsoft).

Една от основните черти на x86 архитектурата е пълната софтуерна оперативна съвместимост с по-старите модели. Това означава, че всеки нов член на фамилията може да изпълнява програмите, създадени за неговите предшественици. Тази съвместимост е една от предпоставките за огромния успех на x86 архитектурата.

x86 архитектурата започва своето съществуване с разработката на процесора Intel 8086 от Intel през 1978 г. 8086 е развитие на техния по-ранен успешен 8-битов процесор 8080. Широкото разпространение на архитектурата започва през 1981, когато IBM избира Intel 8088 (процесор, който е идентичен като програмен модел с 8086) за „сърцето“ на своя персонален компютър IBM PC.

И други компании започват да произвеждат процесори, които са съвместими с 8086/8088. Повечето от тези компании рано или късно се оттеглят от тази област поради огромната конкуренция от страна на Intel, като единствените останали производители са Intel, AMD и VIA (VIA е собственик на бившите IDT и Cyrix).

Първите процесори от семейството x86 (8086, 8088 и 80186) са 16-битови и имат един и същ програмен модел, който се поддържа от всички следващи поколения x86 процесори. След появата на защитения режим, този режим започва да носи наименованието реален режим.

Въпреки ограниченията на реалния режим, при появата си това е била една от най-сложните и универсални процесорни архитектури.

В наши дни реалният режим се използва само при стартирането на операционната система, тъй като всеки x86 процесор веднага след включване на захранването автоматично влиза в реален режим. Това налага първите етапи от зареждането на операционната система да стават в този режим. Популярната в миналото DOS на Microsoft работи почти изцяло в реален режим.

Инструкции за числа с плаваща запетая (x87 инструкции)

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

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

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

Защитеният режим се характеризира с апаратно предотвратяване на достъпа на дадена програма извън границите на заделената ѝ памет. Първата версия на защитения режим се появи в 16-битовия процесор 80286. Въпреки че някои от тогавашните операционни системи (най-вече OS/2 и Windows 3.0) включваха поддръжка за 16-битовия защитен режим, той не получи широко разпространение заради появата на по-универсалния 32-битов защитен режим с пускането на процесора 80386. От този момент под защитен режим ще се подразбира 32-битовият защитен режим на 80386 и следващите x86 процесори.

В съвременните операционни системи се използва защитеният режим на работа. Освен това сегментирането се използва много ограничено, като защитата и управлението на паметта стават основно с помощта на механизма на страницирането. Именно поради тази причина, в 64-битовото разширение на x86 архитектурата AMD64, сегментирането е „орязано“ до минимум.

През 1996 г. Intel въведе ново разширение на x86 архитектурата с пускането на процесора Pentium MMX. MMX означава Matrix Math Extensions (разширения за изчисления с матрици), но по-късно съкращението започна да се дешифрира като Multi-Media Extensions (мултимедийни разширения).

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

Въпреки широката рекламна кампания от страна на Intel, MMX инструкциите дълго време не бяха използвани в приложните програми, а когато такава поддръжка все пак се появи, резултатите не бяха особено впечатляващи. Някои от причините за този скромен успех са:

  • За да не се налагат промени в операционните системи, MMX регистрите всъщност са преименуваните x87 регистри за работа с числа с плаваща запетая. Това не позволява да се използват едновременно MMX и x87 инструкции, а бавното превключване между двата режима допълнително влошава нещата.
  • MMX инструкциите дълго време можеха да бъдат използвани само на асемблер. Поддръжката в програмните езици от високо ниво е ограничена.
  • MMX инструкциите оперират само върху цели числа. Повечето съвременни мултимедийни приложения изискват работа с числа с плаваща запетая.

Все пак, MMX инструкциите станаха част от x86 архитектурата и се поддържат от всички съвременни реализации на тази архитектура.

През 1998 г. с пускането на пазара на процесора K6-2, AMD въведе нов набор от инструкции, наречен 3DNow!. 3DNow! инструкциите са SIMD инструкции, подобни на MMX, но боравещи и с числа с плаваща запетая. Малко по-късно Intel въведе подобен (но по-разширен и несъвместим с 3DNow!) набор от SIMD инструкции, наречени SSE.

В процесорите K6-2+, K6-III и първите Athlon, AMD добави още 19 инструкции за предварително зареждане на данни и др. подобни. Разширеният по този начин набор от инструкции получи името Enhanced 3DNow! (наричани още Extended 3DNow! и 3DNow+). С процесора Athlon XP, AMD въведе третото поколение SIMD инструкции, наречени 3DNow! Professional, като единствената съществена разлика е поддръжката на SSE инструкциите на Intel.

Въпреки че 3DNow! инструкциите се появиха почти година преди SSE инструкциите на Intel, те не получиха широка подкрепа от разработчиците на софтуер, най-вече поради ниския пазарен дял на AMD. Въпреки че отстраняват най-големия недостатък на MMX (невъзможността за работа с числа с плаваща запетая), 3DNow! инструкциите отстъпват по възможности на SSE инструкциите, които използват нови 128-битови регистри и могат да оперират едновременно върху четири 32-битови или две 64-битови числа с плаваща запетая.

В крайна сметка 3DNow! инструкциите загубиха битката с SSE и се поддържат само от процесорите на AMD и VIA и от години не са били добавяни нови инструкции към тях. Като се добави фактът, че AMD процесорите вече поддържат и SSE, бъдещето на 3DNow! изглежда мрачно.

През 1999 г. Intel пусна процесора Pentium III, поддържащ нови SIMD инструкции, наречени SSE (Streaming SIMD Extensions). Също като 3DNow! инструкциите, SSE позволяват паралелната обработка на повече от едно число с плаваща запетая. С въвеждането на SSE, Intel успя да отстрани най-големите слабости на MMX и последвалите ги 3DNow! инструкции.

SSE инструкциите получиха широко разпространение (във всеки случай много по-широко от MMX и 3DNow!) и в крайна сметка AMD добавиха поддръжка за SSE инструкциите в техния процесор Athlon XP и следващите го процесори.

С въвеждането на процесора Pentium 4, Intel добави множество нови инструкции към SSE, създавайки SSE2. SSE2 инструкциите се поддържат от процесорите Athlon 64 на AMD.

С появата на последната ревизия на Pentium 4, Intel въведоха нови допълнения към SSE, наречени SSE3. SSE3 инструкциите се поддържат от последните модели Athlon 64 на AMD.

С течение на времето, SSE, SSE2 и SSE3 инструкциите се наложиха като дефакто стандартни SIMD инструкции в x86 архитектурата, за разлика от 3DNow! инструкциите, които се поддържат само от процесорите на AMD.

В продължение на почти 20 години (от пускането на пазара на процесора Intel 386 до 2003 г.) наборът от инструкции на x86-съвместимите процесори е 32-битов. С течение на времето това започна да се превръща в тясно място, защото 32-битовият процесор не може да адресира повече от 4 GB (232 байта) памет, което се оказва недостатъчно за някои приложения. Intel временно облекчи проблема с модификации в начина на адресиране, но те нито са елегантни, нито особено ефективни.

Гледната точка на Intel по това време беше, че x86 архитектурата вече е изживяла времето си и трябва да бъде замена с перспективната VLIW архитектура IA-64, разработвана от години съвместно с компанията HP. Въпреки теоретичните предимства на тази архитектура, нейната производителност при работа със съществуващите 32-битови приложения е разочароваща, а цената – главозамайваща.

В този момент AMD реши да разработи 64-битови разширения за x86 архитектурата, които бяха кръстени AMD64. Естествено, повечето компании не пожелаха да използват наименованието AMD64 от страх да не предизвикат Intel и в крайна сметка възприеха по-неутралните обозначения x86-64 и x64.

Въпреки коментарите на Intel (както се оказа впоследствие – до голяма степен оправдани), че 64-битовите разширения не са необходими на болшинството от потребителите и няма да бъдат необходими поне още 4 – 5 години, големите компании Microsoft, Sun Microsystems и дори свободната операционна система Linux подкрепиха новата архитектура. Изправени пред тези факти, Intel бяха принудени да приемат като стандарт 64-битовите разширения на AMD, но, разбира се, не под името AMD64, а под името EM64T.

В наши дни поддръжката за x86-64 се превърна в стандарт за процесорите на AMD и Intel, но броят на приложните програми, които реално използват 64-битов код, все още е много малък.

В реален режим всеки x86 процесор има достъп до четиринадесет 16-битови регистъра. Осем от тях (AX, BX, CX, DX, SP, BP, SI и DI) са регистри с общо предназначение. Въпреки това всеки от тях си има свои специфични функции (например достъпа до AX става най-бързо и с най-къса машинна инструкция, а CX се използва за брояч при цикли). Всеки от регистрите AX, BX, CX и DX може да бъде разглеждан и като два 8-битови регистъра, до които има независим достъп (напр. горните 8 бита на DX са 8-битов регистър с името DH, а долните 8 бита – 8-битов регистър с името DL).

Регистрите SP и BP се използват при работата със стека, като първият е указателят на стека, а вторият обикновено се използва от езиците на високо ниво за формирането на така наречения стек фрейм (stack frame) на процедурите. Регистрите SI и DI се използват при формирането на адреса при някои инструкции (най-вече при операции с низове).

Други четири 16-битови регистъра са сегментните регистри CS, DS, ES и SS, които се използват при формирането на адресите. Тъй като с 16 бита могат да се адресират само 64 KB (216 байта), физическият адрес се формира от два компонента – 16-битов адрес от регистър или от самата инструкция, който се събира с умноженото по 16 (т.е. изместено с 4 бита наляво) съдържание на някои от сегментните регистри. По този начин полученият физически адрес е 20-битов, което означава, че максималният обем памет, който може да бъде адресиран в реален режим е 1 MB (220 байта). Кой точно сегментен регистър се използва при изчисляването на адреса зависи от вида на зарежданите данни: CS се използва за инструкциите, DS – за данните, SS – за стека, а ES – при някои инструкции за работа със низове. В повечето случаи е възможно подразбиращият се сегментен регистър да бъде променен с префикс на машинната инструкция.

Регистърът FLAGS съдържа еднобитови флагове, които отразяват текущото състояние на процесора и събития като препълване, пренос към по-старши разред, нулев резултат и т.н. Последният регистър е програмният брояч IP, който съдържа адреса на следващата инструкция, която трябва да бъде изпълнена от процесора.

Въпреки че в реалния режим има зачатъчна сегментация на адресното пространство, тя не разполага с никаква апаратна защита. Сегментите винаги са дълги по 64 KB и нищо не може да попречи да бъдат прехвърлени техните граници.

32-битовият защитен режим дава достъп до същите регистри като реалния режим, но сега всички те са 32-битови вместо 16 битови (с изключение на видимата част на сегментните регистри). Долните 16 бита от всеки регистър са достъпни като 16-битови регистри под същите имена като в реален режим. Целите 32-бита на регистрите са достъпни под имена, които започват с E. 32-битовите регистри с общо предназначение са EAX, EBX, ECX, EDX, ESP, EBP, EDI и ESI, флаговия регистър е EFLAGS, а програмия брояч – EIP. Сегментните регистри си остават 16-битови (но адреса се формира по друг начин, който е обяснен по-долу), като към вече съществуващите CS, DS, SS и ES се прибавят два нови сегментни регистъра, наречени FS и GS.

При защитения режим, процесора се намира в едно от четирите нива на привилегированост, като ниво 0 е с най-високи привилегии, а ниво 3 – с най-ниски. Кода, който работи в дадено ниво, може да прави достъп до данни, които са разположени в същото или ниво с по-ниски привилегии, както и да вика подпрограми, разположени в същото или ниво с по-високи привилегии. Определени системни инструкции могат да се изпълняват само при ниво на привилегированост 0 (т.е. нивото с най-високи привилегии). Въпреки наличието на 4 нива, повечето съвременни операционни системи използват само 2 от нивата – ядрото на операционната система работи на ниво 0, а потребителските програми – на ниво 3.

При разработката на 80386, Intel решават да включат апаратна поддръжка за двете най-разпространени схеми за управление на паметта – сегментиране и страниране. Формираният от дадена инструкция 32-битов ефективен адрес представлява отместване в даден сегмент (област от паметта с начало и размери, които се определят от някой от сегментните регистри). Когато към ефективния адрес се добави началния адрес на сегмента, се получава 32-битов линеен адрес. Ако страниращия механизъм не е активиран, линейния адрес всъщност е и физическия адрес. Ако е активиран страниращия механизъм, линейния адрес се преобразува във физически адрес по начин, който е описан по-долу.

Началният адрес, размера и някои други свойства на сегмента се определят от запис (наричан дескриптор на сегмента) в специална таблица в паметта. Може да има множество такива таблици, като във всеки един момент трябва да има поне 2 дефинирани таблици – глобалната дескрипторна таблица (GDT), която е една и съща за всички процеси; и локалната дескрипторна таблица (LDT), която може да е различна за всеки процес. Адресите на GDT и LDT се зареждат в специални 32-битови регистри. Сегментните регистри съдържат индекс на някои от дескрипторите в GDT или LDT. Чрез този индекс процесора зарежда цялата необходима информация за сегмента от съответната таблица.

Механизмът за страниране на паметта е опционален (може да се изключва). Размера на страниците е фиксиран и може да е или 4 KB или 4 MB. Началните адреси и състоянието на страниците се записват в йерархична организация от таблици (каталози) на две нива, всяка от които съдържа информация за 1024 страници от паметта.

x87 инструкциите наброяват около 60 инструкции, всички започващи с буквата F, за да се различават от стандартните x86 инструкции. Например целочислената инструкция за събиране е ADD, а тази за числа с плаваща запетая – FADD. x87 инструкциите са съвместими със стандарта за изчисления с числа с плаваща запетая IEEE 754 (на практика този стандарт е създаден основно на базата на архитектурата на копроцесора Intel 8087). Обработваните числа включват 32-битови, 64-битови и 80-битови числа с плаваща запетая; 16-битови, 32-битови и 64-битови цели числа и пакетирани BCD (binary coded decimal – отстарял формат при който във всеки байт се комбинират 2 десетични цифри) числа.

x87 инструкциите оперират върху собствен набор от регистри (8 регистъра с имена от ST0 до ST7), които са организирани в стек. Има специални инструкции за прехвърляне на данни от регистрите с общо предназначение към регистровия стек на x87 инструкциите и обратно. Повечето x87 инструкции не могат да оперират върху произволен x87 регистър, а само върху върха на регистровия стек. Тази организация не е толкова ограничаваща колкото изглежда на пръв поглед, тъй като повечето математически изчисления се изпълняват най-естествено с рекурсивен алгоритъм, работещ върху стек от данни.

Мултимедийни и векторни инструкции

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

MMX разширенията представляват SIMD инструкции, които използват 8 целочислени 64-битови регистъра с имена MM0 до MM7. Всеки от тези регистри може да съдържа едно от следните неща:

  • 1 64-битово цяло число
  • 2 32-битови цели числа
  • 4 16-битови цели числа
  • 8 8-битови цели числа

MMX инструкциите позволяват да се изпълни една и съща математическа операция (например събиране, изваждане и т.н.) едновременно върху всички числа, пакетирани в някои от MMX регистрите.

3DNow! инструкциите работят върху същите регистри като MMX инструкциите. Във всеки от 64-битовите MMX регистри може да се разположат две 32-битови числа с плаваща запетая, което се обработват едновременно от 3DNow! инструкциите. Първоначалният набор, въведен с процесорите K6-2, включва 21 инструкции за работа с числа с плаваща запетая и с цели числа, както и по-бързо превключване между MMX/3DNow! и x87 режимите на работа.

SSE съдържа 70 нови инструкции и 8 нови 128-битови регистъра с имена от XMM0 до XMM7. Всеки от тези регистри съдържа четири 32-битови числа с плаваща запетая, които се обработват едновременно от SSE инструкциите.

Основната промяна в SSE2 е възможността да се обработват 64-битови числа с плаваща запетая, както и 8/16/32-битови цели числа.

В SSE3 са добавени предимно специализирани Digital Signal Processor (DSP) инструкции.