Создание программ
Создание программ
Программное обеспечение любой вычислительной системы можно условно разделить на два типа: системное и прикладное. Примеры системного программного обеспечения — операционные системы, ассемблеры и компиляторы. Прикладное же программное обеспечение обычно предназначается непосредственно для пользователей и решает конкретные задачи.
Ранее считалось, что доступ к архитектуре самого нижнего уровня посредством ассемблера необходим как системному, так и прикладному программисту. В пользу этого суждения приводилось множество аргументов: большинство программ имели доступ к крайне незначительному объему памяти, процессоры были медленными и дорогими, а компиляторы с языков высокого уровня — не слишком хорошими. Когда нужно было «выжать последний грамм» для повышения производительности компьютера, «настоящие» программисты использовали язык ассемблера.
Теперь же появилось много приверженцев мнения, что программирование на языке ассемблера — реликт прошлого. Но это не так. Большинство используемых ныне операционных систем (не только старых, чьи корни которых восходят к 60-м и началу 70-х годов, но и более современных) включают в себя большие объемы кода на ассемблере. Таковы, например, операционные системы для ПК: Windows 95 фирмы Microsoft написана по большей части на языке ассемблера Intel.
Первые процессоры для ПК имели достаточно ограниченные возможности. Максимальный размер памяти был равен 64 килобайтам. (Один килобайт равен 210 или 1024 байтам. Байт — это 8-разрядная ячейка памяти, в которой может храниться символ или цифра). Память стоила настолько дорого, что операционные системы могли занимать не более 4 килобайт. Язык ассемблера позволял программистам максимально сокращать размер кода. В результате на нем написан такой большой объем операционных систем, что даже когда размер доступной памяти увеличился благодаря удешевлению технологии, возвращаться назад и переписывать оригинальный код оказалось непрактичным.
Использование ассемблера действительно позволяет оптимизировать размеры и производительность программ. Тем не менее, у этой технологии, по крайней мере, один существенный недостаток: все программы напрямую привязаны к аппаратуре. Любое ее изменение может вызвать необходимость переписать некоторые или даже все программы.
В качестве примера такой ситуации рассмотрим компьютер, имеющий восемь регистров. Регистр — часть тракта данных процессора. Это быстродействующая область памяти, куда помещаются данные и адреса на время их использования процессором. Основное назначение регистров — повышение производительности работы программ. Предположим, что ширина каждого регистра — 16 разрядов, и что программист может помещать данные в регистры и выбирать их оттуда в любой момент по своему усмотрению. Число регистров и их характеристики программист видит из ассемблера. Таким образом, каждая программа для данного компьютера, написанная на этом языке, будет «знать» о восьми регистрах и зависеть от них.
Теперь предположим, что технологический прогресс позволил конструкторам увеличить количество регистров до 16 и сделать их 32-разрядными, причем стоит все это столько же, сколько и оригинальные 8 регистров меньшего размера. Зададимся вопросом: «Как это повлияет на программы, написанные для старого компьютера?». Ответ зависит от того, каким образом были сделаны изменения, и сколь хорошо первоначальная архитектура была спланирована для расширения в будущем.
Допустим, что в старой архитектуре предполагалось расширение до 16 регистров. В каждой команде было зарезервировано достаточно места для адресации 16 регистров, хотя первоначально были реализованы только 8. Для каждой команды, использующей регистры, в данном случае понадобились бы 4-разрядные поля, так как 4 бита позволяют закодировать 16 различных комбинаций нулей и единиц. На новом оборудовании старые программы могут выполняться без изменений. При этом они по-прежнему будут использовать только 8 регистров, новые же программы смогут воспользоваться всеми 16-ю.
А теперь представим себе вместо этого, что в старой архитектуре не были учтены будущие изменения и место для расширения не зарезервировано. Тогда новая архитектура не сможет увеличить количество регистров, не изменив при этом каждую команду, которая их использует. Невозможно растянуть трехбитовые поля в командах до 4 бит, не затронув при этом в той или иной степени существующие программы.
Одна из многих архитектур, неспособных увеличить число пользовательских регистров, — Intel Pentium Pro. Она использует то же количество регистров, что и ее предшественник Intel 386. Хотя увеличение числа регистров дало бы Pentium Pro преимущества, но затраты на переписывание существующих ассемблерных программ слишком велики.
Вообще, увеличение размера регистров с 16 до 32 разрядов оказывает меньшее влияние, чем изменение их количества. Если увеличился только размер, то старые программы будут по-прежнему работать, но использовать лишь 16 из 32 разрядов новых регистров. Данная информация внедрена в логику программы, и ее трудно изменить[ 7 ].
И подобных примеров, когда широко применяемые программы не способны использовать все ресурсы оборудования, — несметное множество. Процессор Intel 386, появившийся еще в 1985 году, имел 32-разрядный дизайн, то есть размер его аппаратных регистров был равен 32 битам. С того времени все процессоры Intel, включая 486, Pentium, Pentium II и Pentium Pro — 32-разрядные. Однако и большинство программ для ПК, использующих эти процессоры, и операционная система DOS были созданы в те времена, когда был доступен только 16-разрядный процессор Intel 286. Даже операционная система Windows 95 написана в основном на 16-разрядном ассемблере. На переписывание прикладных и системных программ ПК под 32-разрядную аппаратуру ушло уже 12 лет, и процесс все еще не завершен.
Эта проблема не ограничивается только индустрией ПК. Прогресс аппаратных технологий поднял планку еще выше: большинство новых процессоров будут 64-разрядными. Чтобы воспользоваться этим более мощным оборудованием, большинство современных 32-разрядных операционных систем и 32-разрядных прикладных программ должны быть переписаны. А это опять долгие годы работы.
В рассмотренных выше примерах модификации аппаратуры состояли в изменении размера и числа регистров процессора. Учтите, что аналогичное влияние на программное обеспечение, написанное на ассемблере, могут оказать и изменения в структуре адресации процессора или в самом наборе команд.
Основная цель программирования только на языках высокого уровня — минимизировать изменения в программах, вызываемые подобными модификациями аппаратуры. К сожалению, в системном программном обеспечении явно наблюдается тенденция перехода на языки, подобные С и С++. Использование С позволяет повысить переносимость системного программного обеспечения, так как компиляторы для этого языка есть на многих аппаратных платформах, но не устраняет все сложности, связанные с изменениями в оборудовании. Некоторые аппаратные характеристики, например разрядность процессора, видимы программисту на С. Такая возможность доступа к внутренним характеристикам привлекательна для системных программистов и объясняет популярность С. Это язык называют «современным ассемблером». В обычной вычислительной системе переход, например, с 32-разрядного процессора на 64-разрядный по-прежнему будет требовать изменений в программе на С. А это снижает переносимость С-программ.
Для иллюстрации рассмотрим опыт Digital. Последние несколько лет эта фирма продает свои машины с 64-разрядным процессором Alpha. Однако две основные операционные системы, используемые на этих компьютерах — Open VMS самой Digital и Windows NT фирмы Microsoft — все еще 32-разрядные, хотя и написаны, в основном, на С. Приложения для этих операционных систем, также 32-разрядные. Простая перекомпиляция здесь не поможет. Чтобы задействовать все ресурсы процессора, и операционные системы, и приложения надо полностью переписать, и это займет много лет.
HP также загнала покупателей своей HP 9000 в трясину переделок. Сейчас HP продает 64-разрядные версии своих процессоров PA-RISC. Чтобы воспользоваться преимуществами новых аппаратных средств, заказчикам HP придется ждать появления новой 64-разрядной ОС, и затем переписывать свои приложения. На это потребуется столько времени, что уже теперь, задолго до того, как переделка ПО будет завершена (см. главу 12), есть признаки того, что HP может отказаться от дальнейшей разработки HP 9000.
Секрет успешного перехода к 64-разрядным вычислениям на AS/400, в то время как никому больше это не удалось, кроется в ее архитектуре.