12 лет назад 5 октября 2006 в 12:17 251

Когда Гордон Мур (Gordon Moore) в 1965 году рассказал всему миру о своем наблюдении, то, судя по всему, он не представлял всех последствий этого доклада. Понятное дело, Мур только предположил, что новые модели микросхем будут появляться каждые 18-20 месяцев, а их емкость будет возрастать при этом примерно вдвое. Тогда он, конечно, и в мыслях не имел открывать свою компьютерную компанию (хотя до появления Intel оставалось совсем немного).

Тем более Мур не ожидал того, что в маркетинговом отделе Intel к его предположению отнесутся со всей серьезностью, восприняв его задумку как руководство к действию. Разработчики чипов оценили служебное рвение маркетологов. По воспоминаниям Билла Пулмана (Bill Pohlman), cразу после появления процессора 8085 (улучшенной версии процессора 8080) маркетинговый отдел Intel стал категорично требовать, чтобы ровно через 18 месяцев – “по закону” – был разработан камень в 10 раз более мощный. Кто такой Билл Пулман? Ну как же, это глава группы, занимавшейся разработкой процессора 8086, перевернувшего мир.

Компьютерный рынок устроен таким образом, что при создании каждого нового продукта (железного или софтового) разработчикам приходится оглядываться на старые. Каждая новая версия программы должна быть совместимой хотя бы по формату файлов с предыдущими версиями. Каждый новый девайс должен по набору команд, сигналам и разъемам соответствовать тому, что уже выпущено.

Творцы наборов MCS-40 и MCS-80 могли проектировать архитектуру своих чипов, не заботясь о том, как откликнется рынок на данные разработки. Строго говоря, они сами формировали этот рынок. Даже упаковав чипы в 16- и 18-пиновые корпусы, разработчики только посмеивались над привычными тогда сороконожками (в то время стандартная микросхема имела длинный корпус с 40 выводами). Но проектировщики чипов 8080, 8085 и 8086 уже были вынуждены учитывать два обстоятельства: во-первых, наличие рынка микропроцессоров с его сложившимися, хоть и недавно, стандартами 8-битного софта, а во-вторых, стандарт на 40-пиновый корпус.

“Проблема 40”

Как удалось решить проблему 8-битного программного обеспечения для чипа 8086, я расскажу чуть позже. Но при чем тут 40-пиновый корпус? Если говорить о процессоре 8086, то “проблема 40” заключалась вот в чем. Система на базе процессора Intel 8086 имела 16-битную шину данных и 20-битную адресную шину. Вот и подсчитайте сами: 20 бит для адреса (линии A0-A19), плюс 16 бит для данных (линии D0-D15), плюс одна выделенная линия для подачи напряжения (Vcc=+5В) и еще одна для подачи синхронизирующих импульсов от тактового генератора на системной плате (CLK). Одну линию обязательно нужно провести к микросхемам памяти для подачи сигнала о том, какое действие с ней (памятью) хочет выполнить процессор – прочитать или записать (RD / WR) информацию. Еще одну линию хоть умри, но выдели под передачу запросов об аппаратных прерываниях, которые могут поступить в любую секунду (INT). Другую – под передачу сигнала RESET, а он, в свою очередь… Стоп, это нам уже 41 линия требуется…

Мда-а… А ведь нужно еще подавать сигналы о том, что микросхемы памяти готовы к обмену данными с процессором (READY), сигнал о немаскируемом прерывании (NMI), сигнал о конфигурации системы (MN/MX) и еще целую кучу управляющих сигналов (Sxx) для согласования действий процессора с внешними устройствами. А вы еще спрашиваете, при чем тут 40-пиновый корпус. Тесноват…

Рис. 1. Блок-схема микропроцессора Intel 8086.
Рис. 1. Блок-схема микропроцессора Intel 8086.

На рис. 1 представлена блок-схема процессора Intel 8086, и на ней хорошо видно, как разработчики справились с “проблемой 40”. Они просто взяли и организовали единую мультиплексорную 16-битную магистраль (на рисунке она обозначена AD15-AD0), которая использовалась и для передачи данных / команд, и для передачи адресов. Вы скажете: “Как же так, адрес-то 20-битный!” И будете совершенно правы, ибо процессор 8086 использовал 20-битный код адреса. Для недостающих бит адреса были выделены еще четыре специальные линии (на рисунке – A19/S6-A16/S3), которые использовались как адресные при передаче… адреса, а в прочих случаях по ним передавались управляющие сигналы.

Магистраль для адреса и данных

Общая шина для адресов и данных была задействована еще в процессоре 8085. Хотя чип 8085 использовал 16 бит для пересылки адресов и 8 бит для пересылки данных, 40 выводов стандартного корпуса ему также не хватало. Поэтому по восьми линиям внешней шины чипа 8085 перебрасывались данные и часть адресных сигналов. Другие восемь линий шины полностью отдавались под вторую группу адресных сигналов. Поскольку процессор 8086 был значительно сложнее, чем 8085, то разработчики “реквизировали” все адресные линии для передачи данных или управляющих сигналов.

Пара слов об основных управляющих сигналах процессора 8086. Сигнал BHE (рис. 1) в комбинации с сигналом на линии адрес / данные AD0 регулировал процесс передачи данных. Это осуществлялось следующим образом: либо два байта передавались сразу по линиям D0-D15, либо, если нужно было переслать один байт, задействовалась группа линий D0-D7 или D8-D15. Сигнал BHE “делал” шину данных либо 16-битной, либо 8-битной. Именно таким образом достигалась совместимость процессора Intel 8086 с 8-битным программным обеспечением.

Как же работал процессор, который использовал одни и те же линии и для адресов, и для данных, и даже для некоторых управляющих сигналов? На рис. 2(a) показана схема синхронизации шины адрес / данные процессора 8086 (“тайминги”). На схеме видно, что цикл обмена данными между процессором 8086 и памятью состоял из пяти тактов: четырех рабочих (T1, T2, T3, T4) и одного такта ожидания (Twait). На такте T1 передавался адрес, а циклы T2, T3, Twait, T4 использовались для обмена данными и передачи дополнительных управляющих сигналов.

Схема синхронизации шины
Рис. 2. Схема синхронизации шины микропроцессоров Intel 8086 (а) и Intel 8088 (б).

Например, сигналы S3-S4 посылались одновременно с отправкой данных и несли информацию о типе сегмента, с которым происходит обмен данными. Сигналы S2-S0 использовались контроллером шины на системной плате (микросхема Intel 8288) для оповещения модулей памяти и портов ввода / вывода о начале операций по обмену данными. Например, комбинация 001 на линиях S2-S0 обозначала операцию чтения из порта, 010 – запись в порт, 101 – чтение памяти, 110 – запись в память. Узел процессора 8086, отвечавший за управление шиной адреса / данных, получил название “модуль интерфейса шины”.

Разберем подробнее работу этого устройства. Тактовый генератор на системной плате (микросхема Intel 8284A) выдает первый импульс (сигнал T1), и блок управления (БУ) процессора посылает в модуль интерфейса шины некий адрес (о схеме адресации памяти – ниже). Модуль интерфейса шины, который также получил импульс T1 и “знает”, что на данном такте внешняя шина используется для передачи адреса, задействует линии с A0 по A19 для пересылки в память адреса. С помощью сигнала ALE (Address Latch Enable) включается запрет на любое другое использование адресной шины на этом такте.

Затем микросхема 8284A вырабатывает следующий синхронизирующий импульс (процессор его воспринимает как сигнал о начале такта T2). Модуль интерфейса шины путем посылки сигнала по линии BHE и AD0 настраивает шину (16-битная или 8-битная, а если 8-битная, то какая группа линий используется, старшие 8 бит или младшие 8 бит – D0:D7 или D8:D15). Одновременно модуль посылает сигнал RD или WR, исходя из того, какое действие с памятью хочет произвести процессор (прочитать или записать).
Микросхема 8284A снова вырабатывает импульс (такт T3). Если перед этим был послан сигнал WR (запись), то в оперативную память сразу же отправляются данные из какого-либо регистра общего назначения (в соответствии с настройками шины данных сигналом BHE: 8 бит или 16 бит). Передача данных в память занимает целых три цикла, включая и цикл ожидания: T3, Twait и T4. Если же на втором такте был передан сигнал RD (чтение), то модуль интерфейса шины резервирует шину под прием данных и начинает прием данных в конце следующего цикла (Twait).

Что делает модуль интерфейса с информацией, поступившей из памяти? Если из памяти пришел код команды, то он отправляется в очередь команд, если данные, то они “уходят” в один из регистров общего назначения. А как модуль интерфейса шины отличает код команды от данных? Его об этом информирует БУ (блок управления). Именно БУ заботится о том, чтобы четко выполнялся внутренний цикл: [дешифровка команды] – [выполнение команды] – [чтение следующей команды]. Cразу после дешифровки команды БУ сообщает модулю интерфейса шины, что шина будет использована для получения данных (или для их отправки). А сразу после выполнения очередной команды БУ вырабатывает сигнал о том, что из памяти нужно получить новую команду.

Конфигурация системы

Еще одна маленькая деталь. Система на базе процессора 8086 могла иметь так называемые минимальную (MN) и максимальную (MX) конфигурации. Настройка процессора на ту или иную конфигурацию осуществлялась подачей управляющего сигнала MN / MX (см. рис. 1). В минимальной конфигурации отсутствовал контроллер шины (чип Intel 8288), процессор управлял внешней шиной с помощью сигналов DT / R (Data Transmit / Receive) и DEN (Data Enable). Но общая схема работы ядра процессора оставалась неизменной при любой конфигурации.
Для процессора Intel 8086 нужно было специально разрабатывать новую системную плату с 16-битной шиной данных. А это неминуемо должно было привести к увеличению общей стоимости системы в целом и автоматическому ее выпадению из рыночного сегмента “16-битный персональный компьютер за 1500 долларов”. Поэтому инженеры IBM для своего проекта 5150 (IBM PC) взяли за основу другую разработку Intel – чип 8088, появившийся в 1979 году.

Традиционным определением процессора Intel 8088 является следующая фраза: “Это процессор 8086 с 8-битной шиной данных”. На такой характеристике настаивал в первую очередь маркетинговый отдел Intel. Но правильнее было бы назвать чип 8088 “процессором 8085 с набором команд x86 и регистрами Intel 8086”. Некоторые компании (в частности, Godbout Electronics), выпуская клон 8088, позиционировали его именно как решение из одной группы с чипом 8085 (их оригинальная документация так и называется – “CPU 8085 / 88 Technical Manual”). Клон 8088 от компании Godbout Electronics имел даже синхронизацию, аналогичную 8085, и базовый четырехтактовый цикл (у оригинального 8088 от Intel базовый цикл равен пяти тактам, см. рис. 2(б). Для программистов, конечно, это особого значения не имело, поскольку и 8086, и 8088 располагали одним и тем же набором команд. Однако если быть совершенно беспристрастными, то оригинальный IBM PC нельзя назвать полноценной 16-битной машиной.

Регистры и работа с памятью

Вычислительная мощь процессора 8086 (и 8088) строилась на наборе из четырнадцати 16-битных регистров, объединенных в несколько групп (они изображены на рис. 4). Основа набора – регистры общего назначения: AX (аккумулятор), BX (база), CX (счетчик) и DX (данные). Размерность каждого из них – 16 бит, но для совместимости с программным обеспечением процессоров 8080 и 8085 к регистрам общего назначения программа могла обращаться и как к 8-битным.

Рис. 4. Регистры микропроцессора Intel 8086 (8088).
Рис. 4. Регистры микропроцессора Intel 8086 (8088).

Для этого каждый регистр был разделен на две части: старший байт (Height) и младший (Low). Если программист собирался обратиться к регистру как к 16-битному, то после имени регистра (A, B, C или D) ставил символ X (AX, BX, CX, DX). Но если ему требовалось использовать регистры общего назначения как 8-битные, то он к имени регистра прибавлял литеру H или L в зависимости от того, к какому байту регистра (старшему или младшему) нужно было обратиться. Это позволяло легко адаптировать старое 8-битное ПО, поскольку литеры A, B, C и D (но без второй буквы) в качестве имен регистров применялись еще в процессоре 8085.

При организации работы с памятью разработчики Intel нашли решение, которое тогда, видимо, показалось изящным, но позднее подвергалось страшным проклятьям. Так как необходимо было добиться частичной совместимости нового чипа с ПО для 8-битных процессоров (8080, 8085 и Z80), разработчики не стали отказываться от 16-битной схемы адресации памяти (в предыдущих чипах для хранения адресов памяти применялись 16-битные регистры). Однако 16-битный адрес позволяет использовать максимум 64 кбайт памяти. Такой объем уже не мог удовлетворить серьезного пользователя ПК. Как быть? Решили разбить общее пространство памяти на так называемые сегменты – виртуальные умозрительные части с максимальным объемом 64 кбайт каждая.

Количество сегментов в оперативной памяти ограничивалось размерностью регистров (16 бит) и не могло превышать 65 535; каждый сегмент отстоял от другого на 16 байт. Каждая выполняющаяся программа для процессора 8086 (8088) состоит из нескольких сегментов. Во-первых, есть сегмент кода (Code Segment) – массив команд, предназначенных для выполнения. Во-вторых, существует регистр данных, в котором содержится информация, подлежащая обработке (Data Segment). В-третьих, если одного сегмента данных мало, программист может задействовать дополнительный сегмент данных (Extra Segment). И наконец, в-четвертых, почти каждая программа включает в себя сегмент стека для временного хранения данных и для обмена параметрами между подпрограммами (Stack Segment).

Для хранения номеров этих сегментов в процессоре 8086 есть кодовые регистры: CS, DS, ES и SS. Каждый из сегментных регистров (их имена являются аббревиатурами названий соответствующих сегментов) должен хранить ссылку только на сегмент своего типа. Например, в регистре SS не может содержаться только номер стекового сегмента.

Реальный адрес требуемой ячейки памяти определялся довольно затейливо по схеме СЕГМЕНТ:СМЕЩЕНИЕ на основании значений в двух регистрах: сегменте и регистрах-указателях. Происходило это так: справа к значению СЕГМЕНТ приписывалось четыре нуля, и к полученному числу прибавлялось значение СМЕЩЕНИЕ. Смещение внутри сегмента выбиралось из регистров-указателей SP, BP, SI, DI или регистра IP (указателя команд – Instructions Pointer).

Например, в регистре SS хранится номер сегмента 0000 0011 0000 1111, а в регистре SP – номер ячейки внутри этого сегмента, скажем, 0000 0000 0000 0101. Тогда реальный адрес ячейки в общем массиве памяти вычисляется так: сначала справа к значению SS приписывается четыре нуля (все биты сдвигаются влево на четыре позиции), в результате имеем 0000 0011 0000 11111 0000; а затем к полученному числу прибавляется значение из SP; получается 20-битный адрес 0000 0011 0000 1111 0101, или 030F5 в шестнадцатеричном виде. Этот адрес процессор посылает для доступа к нужной ячейке памяти. Рис. 3 иллюстрирует эту схему.

 Рис. 3. Организация работы с памятью микропроцессора Intel 8086 (8088).
 Рис. 3. Организация работы с памятью микропроцессора Intel 8086 (8088).

Архитектура уровня команд

Рассуждая об архитектуре любого процессора, всегда следует понимать разницу между его внутренним устройством как таковым (регистры, АЛУ, блок управления, внутренняя шина, конвейер и т. д.) и архитектурой уровня команд ассемблера. Строго говоря, термин “архитектура x86” относится как раз к уровню команд Ассемблера. Это значит, что программист, используя ассемблер, будет всегда иметь дело с одной и той же абстрактной архитектурой x86 вне зависимости от того, какой процессор установлен на конкретной машине. Сразу оговорюсь: каждая модель процессора обладает собственным, уникальным расширением базового набора команд. Например, во многом отличие камней Intel от камней AMD заключается в наборе команд для мультимедиа.

Чипы Intel Pentium поддерживают комплекс мультимедиаинструкций SSE и SSE2 (с базовым набором команд MMX). А AMD Athlon и Duron не поддерживают наборы SSE и SSE2, зато имеют собственный набор аналогичных инструкций – 3DNow! и Enhanced 3DNow!. В этом смысле их архитектуры существенно различаются на уровне команд. Но в основе набора команд у процессоров Intel, AMD, Cyrix, да и у любого другого процессора архитектуры x86 лежат инструкции самого первого процессора семейства – Intel 8086. Именно поэтому на любом процессоре x86 может быть запущена программа, написанная для Intel 8086.

Вот и все, что можно рассказать о процессоре Intel 8086 и его работе в рамках одной статьи. Так все работало 15 лет назад, но, в принципе, точно так же работает и сегодня. Ну, разве чуть побыстрее. Впрочем, кое-какие отличия имеются. Но об этом мы поговорим в следующих статьях.

Дмитрий Румянцев

Никто не прокомментировал материал. Есть мысли?