Една хардуерна корекция в процесора Intel 8086

Най-четени

Даниел Десподов
Даниел Десподов
Новинар. Увличам се от съвременни технологии, информационна безопасност, спорт, наука и изкуствен интелект.

Оригиналът е на изключително популярния хардуерен специалист Ken Shirriff

Микропроцесорът 8086 е революционен чип, представен от Intel през 1978 година. Неговата поява доведе до това, че процесорната архитектура и до днес доминира в сферата на десктоп компютрите и сървърите. При реверсивното инженерство на 8086 по снимките на неговия кристал моето внимание бе привлечено от една верига, понеже нейната физическа структура не съответстваше на околните други вериги. Оказа се, че тази верига реализира специфична функционалност за две процесорни команди, като променя начина на тяхното взаимодействие с прекъсванията в чипа. Потърсих допълнителна информация и разбрах, че това е добавено от Intel през 1978 година с цел да се отстрани неприятен проблем с първите версии на чипа 8086. Изучавайки кристала на този чип може да се разбере по какъв начин Intel се е справял с бъговете в процесора 8086.

Една хардуерна корекция в процесора Intel 8086

В съвременните CPU бъговете обикновено се оправят с помощта на ъпдейти за микрокода. Но преди появата на Pentium Pro, което стана през 1995 година, грешките в микропроцесорите можеха да се обновяват само чрез добавянето на допълнителни вериги със собствена логика директно върху силиция. За Intel бе голям проблем когато се прояви историческия бъг в Pentium при делене с плаваща запетая. Оказа се, че в този чип има бъг, който води до редки, но сериозни грешки при този тип делене. През 1994 година Intel изтегли дефектните процесори и ги замени, което струваше на процесорния гигант немалките $475 милиона.

Електрическата схема на кристала

 На снимката по-долу е показан кристалът на 8086 с обозначени основни функционални блокове. Вижда се, че върху силиция е нанесен метален слой. В съвременните чипове може да има над една дузина метални слоеве, но процесорът 8086 имаше само един. Вижда се и че от всички страни на кристала излизат проводници, които са свързани с 40-те крачета на процесора.

Една хардуерна корекция в процесора Intel 8086

В този случай за нас е най-важен блокът Group Decode ROM в горната част на чипа. Този модул осъществява разделянето на процесорните команди на групи според начина на тяхното декодиране и обработка. Така например, най-опростените команди, като например промяната на флаг, могат директно да се изпълнят само за един цикъл на тактовия генератор. Другите значения в групите не са пълни процесорни команди, а префикси, които се добавят към тези значения и по този начин се образуват пълноценните команди. Останалата част от командите, които не са разпределени в тези групи, са записани в долната дясна част на процесора във вид на микрокод. Много от тези команди имат втори байт (байтът Mod R/M) който указва кой регистър ще се използва и какъв е типът на адресирането. Някои команди имат две версии: едната за 8-битов операнд, а другата – за 16-битов. Някои команди имат бит, който променя местата на източника и на получателя. Group Decode ROM получава 8-битовите процесорни инструкции и решава към коя група принадлежат.

Една хардуерна корекция в процесора Intel 8086
Увеличена снимка на модула Group Decode ROM

На снимката по-горе е показано много по-детайлното изображение на Group Decode ROM. Строго казано, Group Decode ROM повече прилича на PLA (Programmable Logic Array), отколкото на ROM, но Intel го нарече ROM и името си остана. Това е една равномерно разпределена мрежа от логически елементи, която дава възможност за по-плътно разполагане на елементите. Долната част е съставена от NOR елементи, съответстващи на различните шаблони на процесорните команди. Битовете на командите се подават хоризонтално вляво, а всеки NOR логически елемент е поставен вертикално. Изводите на NOR елементите се подават на набора хоризонтални NOR в горната част на този модул и по този начин се осъществяват комбинациите на различните групи.

По-долу е показана силно увеличена част на Group Decode ROM, която всъщност е един NOR. Розовите области са силиций легиран с примеси, за да се получи полупроводник. Сивите хоризонтални линии са полисилиций, който при пресичането си с проводящия силиций образува транзистор. Транзисторите се съединяват помежду си с помощта на метални нишки отгоре. Когато на входа има високо логическо ниво, то включва съответните транзистори и изключва вертикалните линии. Това създава NOR логически елементи с няколко входа. На схемата по-долу са показани два транзистора. Вижда се, че в някои места има транзистори, а в други няма. Именно така е създаден необходимия плътен масив.

Една хардуерна корекция в процесора Intel 8086

Ако малко променим мащаба ще видим, че този PLA е съединен с някаква необичайна схема, която е показана по-долу. Последните две колони в PLA  са твърде интересни. Горната половина не се използва. Вместо това два логически сигнала излизат встрани от PLA хоризонтално и заобикалят горната част на PLA. Тези сигнали отиват към NOR елемент и инвертор, който сякаш е оставен съвсем настрани, понеже е отделен от останалата логика на модула. След това сигналът се подава на NOR с три извода, който по странен начин е разделен на две части. Долната част е обикновен NOR с два входа, но след това е поставен допълнителен транзистор за третия вход (който изучавахме до тук), но е на известно разстояние от него. Отделянето на подобно разстояние е нещо твърде необичайно.

Една хардуерна корекция в процесора Intel 8086

Навярно се затруднявате да разберете какъв е мащабът на тези схеми. Очертаният по-долу с червена линия правоъгълник съответства на областта, която е показана по-горе. Наистина, разглежданият от нас модул заема доста голяма част от кристала.

Една хардуерна корекция в процесора Intel 8086

Естествено, реших да разбера на кои процесорни инструкции оказва влияние тази загадъчна и допълнително добавена схема. Разгледах по-подробно шаблона и състоянието на транзисторите в Group Decode ROM и определих, че двете интересуващи ни колони съответстват на процесорните инструкции с битове  10001110 и 000xx111. От документацията на 8086 разбрах, че вторият съответства на инструкциите MOV sr,xxx за поставяне на значение в сегментния регистър. Първият шаблон (байт) съответства на процесорната инструкция POP sr, за изваждане на значение от стека и неговото прехвърляне в сегментен регистър. Но защо тези инструкции изискват подобно специално отношение?

Бъгът на прекъсванията

Потърсих по-подробна информация именно за тези инструкции открих списък с откритите дефекти в 8086 и 8088 (pcjs.org/documents/manuals/intel/8086), в който се казва следното:

„Прекъсванията, които следват веднага след процесорните инструкции MOV SS,xxx и POP SS могат да повредят данните в паметта. При първите процесори на Intel с надписи „INTEL ‘78“ или „© 1978“, когато прекъсването се осъществи непосредствено след някоя от инструкциите MOV SS,xxx или POP SS, данните се получават от стек с неправилен адрес, а това води до повреда на записаната в паметта информация“.

Оказа се, че именно за премахването на този бъг е необходима тази добавена допълнително загадъчна схема.

Да се спрем малко по-подробно. При 8086, както е при почти всички други процесори, е вградена система за прекъсвания, при която външен сигнал (таймер, клавиатура, вход/изход и т.н) може да прекъсва текущо изпълняваната програма. Процесорът запомня някъде всички свои регистри и започва да изпълнява кода за обслужване на прекъсването, след което се връща към предишната програма, възстановява значението на своите регистри и продължава от същото място, до което е стигнал. При прекъсванията процесорът запазва значенията на своите регистри в свой собствен стек в оперативната памет на устройството и оттам ги възстановява, за да може да продължи с изпълнението на основната програма. Указателят на стека (SP) е регистърът, който показва къде в паметта се намират значенията на този стек.

Една хардуерна корекция в процесора Intel 8086

Особеното тук е, че 8086 използва сегментирана памет, която е разделена на блокове (сегменти), които имат различно предназначение. Процесорът 8086 оперира с четири сегмента: кодовият сегмент (Code Segment), сегментът за данни (Data Segment), стековият сегмент (Stack Segment) и допълнителния сегмент (Extra Segment). За всеки един сегмент се грижи съответния сегментен регистър, в който се записва началния адрес на този сегмент в оперативната памет. Да предположим, че ви се налага да промените текущото местоположение на стека в паметта, за да стартирате нова програма. Ще ви се наложи да промените стековия регистър (Stack Segment, SS) по такъв начин, че той да показа новото местоположение на стековия сегмент. Ще трябва да се промени и регистъра на указателя на стека (Stack Pointer, SP) по такъв начин, че да указва текущата позиция на съответното значение на стека в стековия сегмент.

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

Една хардуерна корекция в процесора Intel 8086

Очевидното решение на този проблем е краткотрайно да се спрат (маскират) прекъсванията по време на промените в регистрите на стека, а след това отново да се пуснат. Това е стандартният класически метод за справяне с прекъсванията, пристигнали в съвсем неподходящ момент. Но проблемът е в това, че 8086, както е и при повечето процесори, има немаскируемо прекъсване (non-maskable interrupt, NMI), което е специално предназначено за най-важните неща и не може да бъде спряно.

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

Особеното е, че премахването на този бъг е твърде мащабно: немаскируемото прекъсване забавя командите MOV и POP за всички сегментни регистри. Няма хардуерни причини за това, понеже самата структура на PLA е такава, че са налични всички необходими битове за всички процесорни инструкции и няма нищо сложно да се направи необходимата проверка единствено за стековия сегмент.

Този метод за отлагане на прекъсването след POP и MOV и до днес се използва от Intel. Само че вече е подобрен и оказва влияние само на регистъра за стековия сегмент и не оказва никакво влияние на другите сегментни регистри.

Регистърът на стековия сегмент може да бъде променен по два начин. Първо, може директно да се запише значение в този регистър (MOV SS, xxx на асемблер) или да се извлече съответното значение от стека в регистъра на стековия сегмент  (POP SS). Именно на тези две процесорни инструкции оказва влияние тази загадъчна схема. Именно по този начин Intel е добавил необходимата латентност веднага след изпълнението на една от тези инструкции и по този начин се е справил с бъга.

АбонаментВсичко важно от света на технологиите, директно в пощата ти.

С абонирането приемате нашите Условия и Политика за поверителност. Може да се отпишете с един клик по всяко време.


Коментирайте статията в нашите Форуми. За да научите първи най-важното, харесайте страницата ни във Facebook, и ни последвайте в Google Новини, TikTok, Telegram и Viber или изтеглете приложението на Kaldata.com за Android, iPhone, Huawei, Google Chrome, Microsoft Edge и Opera!

1 Коментар
стари
нови оценка

Нови ревюта

Подобни новини