война миров КРИС КАСПЕРСКИ Хакер, номер #074, стр. 084 НЕПРЕДВЗЯТЫЙ СРАВНИТЕЛЬНЫЙ АНАЛИЗ ЭЛЕГАНТНОСТИ АРХИТЕКТУР РАЗЛИЧНЫХ ПРОЦЕССОРОВ ИЗУЧЕНИЕ ДРЕВНИХ ЯЗЫКОВ В ПЕРВУЮ ОЧЕРЕДЬ ПОЗВОЛЯЕТ ОСВОБОДИТЬ МЫСЛЬ ОТ ОКОВ СЛОВА, КОТОРОЕ ВОСПРИНИМАЕТСЯ КАК ЕДИНСТВЕННОЕ ДАННОЕ… ДАЖЕ ЭЛЕМЕНТАРНЫЕ ГРАММАТИЧЕСКИЕ УПРАЖНЕНИЯ ЗАЧАСТУЮ ЗАСТАВЛЯЮТ УЧАЩЕГОСЯ ДРЕВНИМ ЯЗЫКАМ ОСВОБОДИТЬСЯ ОТ КАЖУЩЕГОСЯ ЕМУ ЕДИНСТВЕННЫМ СПОСОБА ВЫРАЖЕНИЯ, ПОЧУВСТВОВАТЬ И УВИДЕТЬ СВОЮ МЫСЛЬ НАСТОЛЬКО МНОГОСТОРОННЕ, НАСКОЛЬКО НИ ДЛЯ КОГО ДРУГОГО ЭТО НЕДОСТУПНО. АЛЕКСАНДР ГИМАДЕЕВ ВВЕДЕНИЕ НЕПРЕКРАЩАЮЩИЕСЯ «СВЯЩЕННЫЕ» ВОЙНЫ ПО ПОВОДУ «X86 ПРОЦЕССОРЫ – ДЕРЬМО, XXX ПРОЦЕССОРЫ – RULES» НЕПРИЯТНЫ В ПЕРВУЮ ОЧЕРЕДЬ ТЕМ, ЧТО ОНИ УНИЖАЮТ И ДИСКВАЛИФИЦИРУЮТ X86-ПРОГРАММИСТОВ В ГЛАЗАХ ВСЕЙ ОСТАЛЬНОЙ ПРОГРАММИСТСКОЙ ОБЩЕСТВЕННОСТИ. ПРИЧЕМ, ПОДАВЛЯЮЩЕЕ БОЛЬШИНСТВО ЗАЩИТНИКОВ X86АРХИТЕКТУРЫ С ПРЕДСТАВИТЕЛЯМИ ДРУГИХ ПРОЦЕССОРНЫХ СЕМЕЙСТВ ЗНАКОМЫ В ЛУЧШЕМ СЛУЧАЕ ПОНАСЛЫШКЕ, А ЕЕ ПРОТИВНИКИ (ЛЬВИНУЮ ДОЛЮ КОТОРЫХ СОСТАВЛЯЮТ ПОКЛОННИКИ PDP-11) СКЛОННЫ УХВАТЫВАТЬСЯ ЗА ОТДЕЛЬНЫЕ, НЕПРИНЦИПИАЛЬНЫЕ АРХИТЕКТУРНЫЕ ОСОБЕННОСТИ, КОТОРЫЕ В X86 РЕАЛИЗОВАНЫ НЕСКОЛЬКО ИНАЧЕ, ЧЕМ В ИХ ЛЮБИМОМ ПРОЦЕССОРЕ. В ОБЩЕМ, АРГУМЕНТЫ ОБОИХ СТОРОН НОСЯТ ГЛУБОКО НЕОБЪЕКТИВНЫЙ И БЕЗДОКАЗАТЕЛЬНЫЙ ХАРАКТЕР, СВОДЯЩИЙСЯ В ОСНОВНОМ К РУГАНИ И НАЕЗДАМ В СТИЛЕ: «МНЕ ПРИШЛОСЬ КАК-ТО ПЕРЕНОСИТЬ ФОРТ С PDP-11 НА I8086, ПРИЧЕМ ПОСЛЕДНИЙ Я ВИДЕЛ ВПЕРВЫЕ… ТАК ОТ АРХИТЕКТУРЫ I80X86 ДО СИХ ПОР ТОШНИТ (ОСОБЕННО ПО СРАВНЕНИЮ С PDP-11)» И «ГОСПОДИ, ДО ЧЕГО ТРУДНО БЫЛО ПРЕОДОЛЕТЬ РВОТНЫЙ БАРЬЕР, ОСВАИВАЯ ПОСЛЕ 5 ЛЕТ РАБОТЫ НА PDP-11 ЭТО ИНТЕЛЕВОЕ СМОЛЯНОЕ ЧУЧЕЛКО :(. КТО РАБОТАЛ НА PDP-11, ДУМАЮ, ПОДТВЕРДИТ». МЫЩЪХ'ЕМ БЫЛА ПРЕДПРИНЯТА ПОПЫТКА ЕСЛИ НЕ ПОСТАВИТЬ ТОЧКУ В ЭТОМ ВОПРОСЕ, ТО, ПО КРАЙНЕЙ МЕРЕ, ДАТЬ СПОРЯЩИМ СТОРОНАМ СВЕЖУЮ ПИЩУ ДЛЯ РАЗМЫШЛЕНИЙ (КАК ЗНАТЬ, БЫТЬ МОЖЕТ ПОСЛЕ ЭТОГО В КОНФЕРЕНЦИЯХ ВМЕСТО РЕПЛИК «САМ ДУРАК» НАКОНЕЦ-ТО ЗАЗВУЧАТ НОРМАЛЬНЫЕ ТЕХНИЧЕСКИЕ АРГУМЕНТЫ). СРАЗУ ОГОВОРИМ, ЧТО НИЖЕ БУДУТ СРАВНИВАТЬСЯ ИСКЛЮЧИТЕЛЬНО ПРОГРАММНЫЕ МОДЕЛИ НЕСКОЛЬКИХ НАИБОЛЕЕ ЯРКИХ РЕЛИЗОВ ПРОЦЕССОРОВ. В ПЕРВУЮ ОЧЕРЕДЬ, ЭТО, КОНЕЧНО, PDP-11 – ЛЕГЕНДАРНЕЙШИХ ПРОЦЕССОР ВСЕХ ВРЕМЕН И НАРОДОВ, ПОРОДИВШИЙ ОГРОМНОЕ КОЛИЧЕСТВО КЛОНОВ (И ОТЕЧЕСТВЕННЫЕ КАЛЬКИ К1801 В ЧАСТНОСТИ), МНОГИЕ ИЗ КОТОРЫХ ИСПРАВНО РАБОТАЮТ И ПОНЫНЕ. ЗАТЕМ СЕРИЮ ПРОЦЕССОРОВ 68K ОТ MOTOROLA, ИЗВЕСТНУЮ В ПЕРВУЮ ОЧЕРЕДЬ ПО ЭПЛАМ РАННИХ МОДЕЛЕЙ И ЕДВА НЕ СТАВШУЮ ОСНОВНОЙ ДЛЯ IBM PC. НАКОНЕЦ, ДЛЯ ПОЛНОТЫ КАРТИНЫ, МЫ РАССМОТРИМ ПРОЦЕССОРЫ СЕМЕЙСТВА DEC ALPHA. МНЕ МОГУТ ВОЗРАЗИТЬ, ЧТО СРАВНИВАТЬ АЛЬФУ СО ВСЕМИ ВЫШЕ ПЕРЕЧИСЛЕННЫМИ ПРОЦЕССОРАМИ НЕ СОВСЕМ КОРРЕКТНО, ПОСКОЛЬКУ ОН СОВСЕМ ИЗ ДРУГОЙ КАТЕГОРИИ. ИМЕННО ТАК! НО ЭТО ЛИШЬ УСИЛИВАЕТ КОНТРАСТ! (КРОМЕ ТОГО, АЛЬФА ОКУТАН ТАКИМ КОЛИЧЕСТВОМ МИФОВ, ДОМЫСЛОВ И ЛЕГЕНД, ЧТО БЛИЗКОЕ ЗНАКОМСТВО С НИМ НИКОМУ НЕ ПОМЕШАЕТ). СРАВНИТЕЛЬНЫЙ АНАЛИЗ ОХВАТЫВАЕТ КАК КЛЮЧЕВЫЕ АРХИТЕКТУРНЫЕ КОНЦЕПЦИИ, ТАК И ИНДИВИДУАЛЬНЫЕ НЕПРИНЦИПИАЛЬНЫЕ АРХИТЕКТУРНЫЕ ОСОБЕННОСТИ, ТАКИЕ КАК, НАПРИМЕР, НАЛИЧИЕ В PDP-11 КОМАНДЫ ОБНУЛЕНИЯ, ОТСУТСТВУЮЩЕЙ В X86 И ВЫНУЖДАЮЩЕЙ ПРОГРАММИСТОВ ИСПОЛЬЗОВАТЬ ЛИБО ПЕРЕСЫЛКУ НЕПОСРЕДСТВЕННОГО НУЛЯ, ЛИБО ЛОГИЧЕСКУЮ ОПЕРАЦИЮ "ИЛИ ИСКЛЮЧАЮЩЕЕ И", ЧТО С ОДНОЙ СТОРОНЫ НИЧУТЬ НЕ УХУДШАЕТ ТЕХНИЧЕСКИЕ ХАРАКТЕРИСТИКИ ПРОГРАММЫ, НО С ДРУГОЙ – СОЗДАЕТ ВПЕЧАТЛЕНИЯ УБОГОСТИ КОНСТРУКЦИИ [система команд.] ЭТО ВЕДЬ ДЕЙСТВИТЕЛЬНО ТАК – X86 ОБЛАДАЕТ САМОЙ ИДИОТСКОЙ АРХИТЕКТУРОЙ И САМЫМ НЕЛЕПЫМ НАБОРОМ КОМАНД ИЗ ВСЕХ НЫНЕ СУЩЕСТВУЮЩИХ ПРОЦЕССОРОВ. ТАК ЧТО ЖЕЛАНИЕ ИЗУЧИТЬ ЕГО ДОСКОНАЛЬНО КАЖЕТСЯ МНЕ ВЕСЬМА СОМНИТЕЛЬНЫМ V. S. LUGOVSKY AKA MAUHUUR
Отличительной особенностью x86 является чрезвычайно богатый набор машинных команд, количество которых в старших моделях Pentium'ов достигает пятисот, что значительно превышает количество команд во всех остальных популярных процессорах вместе взятых! Разумеется, само по себе число поддерживаемых машинных команд еще ни о чем не говорит, напротив, даже вызывает некоторые сомнения в их элегантности. Вспоминается анекдот десятилетней давности: встречаются как-то представители двух функционально одинаковых заводов, один из которых расположен в СССР, а другой в Японии. Вот японский представитель и говорит: «На моем заводе работают восемь человек». А русскому стыдно сказать, что у него работает целая тысяча, и он, слегка приукрашивая действительность, скашивает количество работающих до девяти. На следующий день заметно нервничающий японец спрашивает нашего: «Слушай, я всю ночь не спал, но так и не смог понять: что же у тебя девятый рабочий делает-то?». Действительно, чтобы полноценно программировать на ассемблере x86, нужно очень многому научиться, и лишь немногим программистам удается удержать весь этот набор команд у себя в голове. Постоянным спутником программистов становятся тысячи страниц технической документации, и вместо того, чтобы сосредоточиться непосредственно на решаемой задаче, программист вынужден снова и снова штудировать многочисленные руководства, пытаясь разобраться, в какую же форму следует облечь свою программистскую мысль, чтобы донести ее до «тупой» машины. Ассемблерные программисты уже улыбнулись? И правильно! Ведь большая часть этих пятисот команд относится к векторной и мультимедийной обработке, то есть к прямо таки скажем весьма специфичным областям. Избыточность – она, конечно, карман не тянет (во всяком случае, карман программиста, про производителей процессоров мы намеренно не говорим), но вот многословность, обособленность и косность системы команд уродуют листинги только так! Вот только несколько примеров. Отсутствие адресации – память не позволяет обрабатывать переменные, находящиеся в ней, без пересылки их содержимого во временный регистр (и это при том, что количество регистров общего назначения в x86 процессорах крайне невелико). Команды x86 сопроцессора используют свои – причем крайне примитивные – способы адресации, а потому и синтаксически, и архитектурно обосабливаются от целочисленных команд, что существенно затрудняет как их изучение, так и работу с ними. Ряд машинных команд жестко связан со строго определенными регистрами, и за счет этого произвола многие из них практически полностью обессмысливаются (в частности, привязка счетчика цикла к регистру ECX/CX не позволяет реализовывать вложенные циклы). Наконец, раздельная адресация оперативной памяти и портов ввода/вывода… Процессоры семейства PDP-11 и 68K обходятся значительно меньшим количеством команд, причем удобство их ассемблера было столь велико, что позволяло ему на равных конкурировать с Си и другими языками высокого уровня. Теперь, конечно, программистские веяния изменились, и ассемблер неожиданно выпал из их внимания, но недостатки системы команд x86 процессоров тут совершенно не причем (хотя, некоторые и не разделяют такой точки зрения). Ограниченный объем журнальной статьи не позволяет мыщъх'у рассказать о достоинствах и недостатках каждого из процессоров во всех подробностях, но это, собственно, и не нужно. Зачем жевать уже жеванное (мыщъх'и к жвачным животным не относятся!), когда табличный материал грызть намного удобнее! Перелопатив кучу страниц документации, мыщъх отделил зерна от плевел и складировал их посреди своей норы, получив в итоге очень внушительную (но легкоусвояемую) таблицу 1, готовую к непосредственному употреблению (желательно с пивом). А после употребления пива посмотрим на примеры всем известной программы hello world на разных ассемблерах: Листинг 1. «Hello World» на x86 ассемблере /* * Hello World in gas/NetBSD * AT/T-Syntax * * Compile: * gas hw.s * ld -s -o hw a.out */ .data msg: .string "Hello World\n"
len: .long . - msg .text .globl _start _start: push $len /* Laenge */ push $msg /* Adresse */ push $1 /* Stdout */ movl $0x4, %eax /* write */ call _syscall addl $12, %esp /* Stack bereinigen */
push $0 movl $0x1, %eax /* exit */ call _syscall
_syscall: int $0x80 ret Листинг 2. «Hello, World» на PDP ассемблере ;; Hello world in MIDAS title hello start: .open [.uao,,'tty ? 0 ? 0] .lose %lsfil move 1, [440700,,[asciz "Hello, world"]] loop ildb 2,1 skipn 2 .logou 1, .iot 2 jrst loop end Листинг 3. «Hello, World» на 68k ассемблере start: ; Message-String ausgeben move.l #msg,-(a7) move.w #9,-(a7) trap #1 addq.l #6,a7
; auf Taste warten move.w #1,-(a7) trap #1 addq.l #2,a7
; Programm beenden clr -(a7) trap #1
msg: dc.b "Hello World",10,13,0 На этом наше историческое повествование подходит к концу. Возвращайся в будущее, но не забывай чтить заветы предков :). Из глубины веков «The irony is that the original instruction set was theirs, and the original motivation was theirs». Mazor said. «По иронии судьбы, этот основополагающий набор инструкций был не наш, как и исходная постановка задачи». Стенли Мазор.
Ругая Intel за уродливый (с их точки зрения!) набор инструкций, ее противники зачастую даже и не подозревают, что роль компании Intel в становлении x86 набора инструкций более чем скромна. Собственно, «зачастую» еще слабо сказано. Навряд ли хоть один из спорщиков об этом вообще знает! Но все по порядку… …Давным-давно, когда славные шестидесятые уже подходили к концу, а кремниевая революция семидесятых еще и не думала начинаться, молодая и еще совсем не окрепшая компания Intel неожиданно для себя получила заказ от крупной (по тем временам) японской компании Busicom, поручивший парням из Intel разработку двенадцати микросхем для своих калькуляторов, которыми Busicom тогда занималась. Не то чтобы этот заказ воодушевил руководство Intel, которое прекрасно осознавало, что осуществить такой проект своими силами ей просто нереально, но в бизнесе главное «застолбить» за собой заказ, а там… Авось что ни будь да придумаем! Собственно, так и произошло: ведущий сотрудник Intel примерно в это же самое время обнаружил, что новая метало-оксидно-кремниевая технология дает возможность разместить все компоненты центрального процессора на одной-единственной микросхеме. Сейчас это кажется очевидным, но тогда… Intel просто не поняла, что она изобрела, и, проявив чудовищную недальновидность, «слила» эту технологию окончательно замучившей ее Busicom, которая к тому времени уже, вероятно, и не надеялась получить свои микросхемы. В общем, вместо двенадцати заказанных микросхем Intel предложила сделать всего одну супер-микросхему, реализующую функции всех их. Такой поворот событий не очень-то обрадовал японцев (точнее - совсем не обрадовал). По началу они даже едва не отказались, но, хорошенько подумав, решили, что лучше синица в руке, и приняли работу. Приблизительно в это же самое время до руководства Intel доходит, что было у них в руках и что они упустили. Все, что остается… «Лететь в Японию и вести с Busicom переговоры», выкупая у ошарашенных японцев только что проданный им чип… Впрочем, вернемся к непосредственному предмету нашего разговора – разработке системы команд для вновь созданного микропроцессора. Система команд первого в мире микропроцессора по-видимому разрабатывалась двумя людьми, – собственно самим Тедом Хофом и присоединившимися к нему впоследствии Стенлом Мэйзором. Другие же источники утверждают, что она была естественным путем содрана с процессоров IBM и Digital. Что ж! Дотошным читателям еще во многом предстоит разобраться, мне же искать описание чипа Intel 4004 и скрупулезно сравнивать его с продукцией остальных компаний просто лень. Как бы там ни было, система команд Intel 4004 не имела будущего и в скором времени умерла. http://www.cs.cuw.edu/csc/csc425/4004card.html.[n1] История x86 начала свой отсчет несколько позднее. Немногое подробности уцелели с той поры, – вот практически все, что мне удалось раскопать. В том же 1969 году Intel получила заказ от техасской компании Computer Terminal Corporation (в последствии переименованной в Data-Point) на интегрирование разработанного ею процессора в кристалл кремния. Обратите внимание, – именно интегрирование, а отнюдь не самостоятельную разработку, как это было в случае с Busicom. Другими словами, от Intel требовалось создать микропроцессор в полном соответствии со всеми предоставленными спецификациями, в которые, естественно, входило и полное описание набора машинных команд для терминал. Используемая Data-Point система команд была… нет, не плохой, скорее, ее можно назвать примитивной, но для терминалов – вполне достаточной. Действительно, терминалы (даже интеллектуальные!) не особо-то притязательны, и излишняя элегантность и архитектурные изыски им абсолютно ни к чему. Сегодня, когда миллиарды транзисторов стоят дешевле качественных компьютерных корпусов (а не этих дребезжащих китайских жестянок), трудно поверить, что еще совсем недавно за каждый транзистор приходилось платить, и железо с избыточной функциональностью просто не окупалось. Счетные задачи решал центральный процессор, установленный на главной машине. Терминал занимался лишь вводом и отображением данных, то есть обеспечивал то, что сегодня называется интерфейсом. Ну да, разумеется, никакой интерактивности (в сегодняшнем понимании этого слова) там и не ночевало, и основным средством общения с компьютером была командная строка. Соответственно, и набор инструкций был ориентирован на управление, а не на вычисления и математическую обработку. К тому же, поскольку программное обеспечение терминала, зашитое в его ПЗУ, не меняется каждый день, на удобство программирования терминального процессора всем было глубоко начхать, и никакой элегантности от его системы команд попросту не требовалось (кого из нас, сегодняшних, волнует система команд, ну, скажем, процессоров модема?). Реализация микропроцессора заняла практически три года. Лучшие инженеры компании, увлеченные своими идеями, работали практически на пределе человеческих возможностей, отдавая процессору и дни, и ночи, и выходные. «Они являлись на работу к восьми утра и работали до шести вечера, забывая сделать перерыв на обед. Они просыпались задолго до восхода солнца, чтобы опробовать идею, внезапно пришедшую им в голову. Часто семьи разваливались». Когда же «младенец» наконец заработал, компания Data-Point переживала не лучшие времена и потому отказалась выплачивать положенную по контракту сумму, ссылаясь на то, что микропроцессор слишком медлителен и к тому же требует чрезмерно большого количества микросхем поддержки. В качестве отступного компании Intel были переданы все права на систему команд микропроцессора, – не слишком-то хорошее утешение, но все-таки лучше, чем совсем ничего. Такой поворот событий, признаться, сильно озаботил Intel, и она начала продвигать микропроцессор 8008 (а именно такое обозначение он получил) собственными силами. И это, надо сказать, ей удалось! Новый чип нашел широкое применение не только в микроконтроллерах, но и в первых персональных компьютерах только-только начавших появляться к тому времени. Кстати, одна из распространенных легенд гласит, что первым персональным компьютером был «Альтаир», но это неправда! «Альтаир», основанный на 8080, появился несколько позднее. Его опередило больше количество микро-ЭВМ, и RGS-08 с «Марком» в частности. Конечно, это были очень и очень простые машины, основанные на 8008, который поддерживал набор из 45 команд и мог непосредственно адресовать аж 16 Килобайт (не улыбайтесь, – по тем временам эта величина была весьма нехилой). Вот так, собственно, все и завертелось. Следующий микропроцессор, представленный Intel, – 8080 - не был, да и не мог быть подлинно революционным. Да, разработчики добавили тридцать новых команд, увеличили непосредственно адресуемое пространство до 64 Кб, кое-что исправили по-мелочи, но на принципиальное улучшение архитектуры они не отважились. Да и кому, собственно, принципиально новый процессор был нужен? На базе 8080 процессора было собрано большое количество микрокомпьютеров, обросших за время своего существования большим количеством программного обеспечения. Операционная система CP/M, текстовой редактор WordStar, база данных dBase… Популярность этих программ была столь велика, что их веяния прослеживаются до сих пор! А потому всякая мысль об отказе обратной совместимости в последующих моделях процессоров представлялась руководству Intel и экономически, и политически убийственной, но… Они все-таки сделали это, благодаря чему все мы сидим под x86, а не решись инженеры Intel в свое время на достаточно рискованный шаг по усовершенствованию архитектуры своего процессора, – его бы уже давно вытеснила Motorola 68K или DEC Alpha. Новое детище – 8086, (кстати, на момент своего рождения заметно обогнавшее и время, и рынок) не обеспечивало прямой бинарной совместимости с 8080 (то есть не могло выполнять уже откомпилированные программы) и было совместимо лишь на уровне ассемблера (при наличии исходных текстов проблема переноса решалось простой перекомпиляцией). Система команд претерпела значительные изменения (не все из которых, впрочем, пошли ей на пользу), но вместе с дополнительными возможностями приобрела некоторую плебейскую разношерстность и печально известную сегментную модель памяти. «И откуда только появились эти чертовы сегменты?!», – вздыхали программисты начала восьмидесятых - конца девяностых. Неужто эти идиоты из Intel не могли придумать, как обойтись без них? Что ж, попробую ответить. Сегменты, собственно, и появились потому, что 8086 опередил свое время, ухитряясь адресовать аж 1 Мб памяти вместо «положенных» ему 64 Кб. Действительно, при побайтовой адресации памяти 16-битные указатели могут «бить» лишь в пределах одного 64 Кб блока, а ведь 8086 и был 16-разрядным! Можно, конечно, пойти на хитрость и адресовать память не байтами, а словами (и некоторые процессоры именно так и делают!), – тогда объем непосредственно адресуемой памяти возрастет до 128 Кб, но… Во-первых, это все равно не выход, а во-вторых, такое решение идет вразрез с требованием об обратной совместимости. Наконец, сам объем непосредственно адресуемой памяти, - каким бы большим он ни был, – еще ничего не дает! И чтобы им эффективно воспользоваться, необходимо иметь как минимум возможность создания перемещаемых программ, – то есть, попросту говоря, уметь загружать программу в любое место памяти. Многие микрокомпьютеры начала восьмидесятых (в том числе и те, что были собраны на базе 8080) выделяли программам фиксированные участки памяти, и потому загрузка нескольких программ становилась весьма проблематичной. (В частности, «Stealth»– отладчики тех лет - грузили себя в буфер экранной памяти, отъедая несколько нижних строк, и, естественно, код отладчика отображался на терминале в виде бессмысленного мусора, зато такой отладчик не конфликтовал с программами!). К более подробному обсуждению преимуществ и недостатков сегментной модели памяти мы еще вернемся, а пока же заметим лишь то, что сегментная организация памяти намного удобнее страничной адресации, используемой в машинах типа PDP-11 и намного дешевле 32-разрядных указателей, используемых в процессорах типа 68K. |