Программа является машинно-зависимой, если при ее разработке необходимо учитывать особенности архитектуры. Например, генератор кода в любом компиляторе является машинно-зависимой частью
Вид материала | Программа |
- Примерная инструкция по охране труда при подготовке к работе сельскохозяйственных машин, 301.45kb.
- Рабочая программа дисциплины «Машинно-зависимые языки программирования» Направление, 136.33kb.
- Качественная работа машинно-тракторного пахотного агрегата позволяет хорошо подготовить, 410.19kb.
- И программа 13-ой Международной научно-практической конференции машинно-технологическое, 257.75kb.
- Е. А. Цветков Московский физико-технический институт (государственный университет), 381.58kb.
- Неотъемлемой частью работ при разработке или модификации программных систем является, 22.36kb.
- Одним из эффективных математических методов для определения зависимости по множеству, 139.29kb.
- А тесноту связи между зависимой и независимой переменными, 526.21kb.
- Вопросы по курсу «Допглавы эконометрики» Преподаватель : доцент, к ф. м н. Пяткина, 7.26kb.
- Контрольная работа по гражданской обороне, 433.65kb.
Глава 1. Системное программное обеспечение и архитектура ЭВМ
Системное программное обеспечение, будь то операционная система, ассемблер или компилятор для какого-нибудь языка высокого уровня, всегда создается для конкретной вычислительной машины. Машинная зависимость является одной из характерных особенностей, которая во многом отличает системное ПО от прикладного. При разработке прикладной программы основное внимание сосредоточено на предметной стороне дела, и особенности конкретного компьютера мало влияют на программу — ЭВМ используется только как инструмент для решения задачи. С другой стороны, операционная система обычно реализуется для конкретной вычислительной системы, и на другом компьютере работать не будет. А инструментальное программное обеспечение по сути своей предназначено для создания программ на конкретную машину. В этом смысле системные программы практически всегда зависят от компьютера, поэтому системный программист должен прекрасно разбираться в устройстве вычислительных машин.
ЭВМ можно изучать под разным углом зрения. Например, можно рассматривать компьютер как набор связанных функциональных блоков различного назначения. С другой стороны, можно изучать множество логических элементов, и как они используются при построении функциональных блоков. Инженеров-электронщиков, очевидно, интересуют электрические схемы и прохождение сигналов. Такие описания представляют собой различные модели компьютера, предназначенные для изучения их человеком. Вместо слова «модель» часто употребляется термин «спецификация» или «архитектура».
Программисты используют совсем другую модель. Модель компьютера для программиста называется архитектурой команд [_] или просто архитектурой.
Программа является машинно-зависимой, если при ее разработке необходимо учитывать особенности архитектуры.
Например, генератор кода в любом компиляторе является машинно-зависимой частью.
Важнейшими особенностями архитектуры, которые оказывают наибольшее влияние на разработку системного программного обеспечения, являются следующие:
- типы данных, которыми способен оперировать процессор;
- организация памяти и состав регистров процессора;
- набор команд и способы адресации аргументов.
При реализации операционной системы обязательно рассматривать еще организацию системы прерываний и системы ввода-вывода.
С другой стороны, системное программное обеспечение имеет ряд аспектов, которые совершенно не зависят от типа вычислительной системы. Например, архитектура ЭВМ никак не влияет на синтаксический анализ программы, выполняемый любым компилятором. На работе мейкера тоже никак не отражаются ни организация памяти, ни набор регистров. В трансляторе с ассемблера не зависит от архитектуры команд «сбор» меток в таблицу имен. Даже в операционной системе есть машинно-независимые компоненты, например, командный процессор.
При изучении системного программного обеспечения желательно четко отделить машинно-зависимую часть от остальных. Такое деление позволит сосредоточиться на действительно важных характеристиках системных программ. Помимо всего прочего явное отделение машинно-зависимой части существенно облегчает перенос ПО на другую архитектуру.
Реальные и виртуальные компьютеры
В настоящее время различают несколько различных типов архитектур [_]:
- архитектура с полным набором команд (Complex Instruction Set Computer, CISC);
- архитектура с сокращенным набором команд (Reduced Instruction Set Computer, RISC);
- архитектура с безоперандным набором команд (Removed Operand Set Computer, ROSC).
В наши дни наиболее распространена архитектура CISC. Характерными чертами такой архитектуры являются:
- небольшое число регистров общего назначения;
- большое количество машинных команд, некоторые из которых весьма сложны;
- разнообразие способов адресации операндов;
- множество форматов команд различной длины.
Типичным представителем компьютеров с такой архитектурой является Pentium [_].
Архитектура с сокращенным набором команд обладает прямо противоположными характеристиками:
- большое количество регистров общего назначения;
- относительно небольшое множество простых машинных команд;
- количество способов адресации ограничено; фактически все команды, кроме команд загрузки и сохранения, выполняют операции на регистрах;
- команды имеют одинаковую длину, и количество форматов команд ограничено.
Все это позволило существенно упростить аппаратуру и значительно повысить быстродействие. Как правило, такая архитектура используется в суперЭВМ вроде Cray. Однако и микропроцессоры «доросли» до RISC.
Архитектура с безоперандным набором команд основана на применении стека. Появление ROSC-архитектуры вызвано стремлением сократить семантический разрыв [_], существующий между языками высокого уровня и аппаратурой компьютера. Стеки широко используются в компиляторах для реализации языков высокого уровня. И в оттранслированной программе стеки используется тоже очень широко. Например, вложенные или рекурсивные вызовы подпрограмм, реализация локальной области видимости, вычисление арифметических выражений проще всего выполнить с помощью стека.
В настоящее время можно наблюдать тенденцию сближения архитектур. Например, в микропроцессоре Pentium мы можем обнаружить элементы и RISC-архитектуры, и ROSC-архитектуры [_]. Однако большинство реальных ЭВМ по тем или иным причинам часто обладают нестандартными или даже уникальными особенностями. В том же Pentium многочисленные методы адресации разрешается задавать только для одного из операндов, а второй непременно должен быть в регистре. Кроме того, регистры (базовый и индексный), используемые для формирования адреса операнда, задаются неявно с помощью комбинации 5 битов в специальном байте modR/M в составе команды. Мало того, в формировании физического адреса помимо аргументов в команде неявно участвует один из сегментных регистров. Обычно он выбирается процессором по умолчанию в зависимости от команды и метода адресации, однако его можно назначить принудительно с помощью префикса замены сегмента.
Такие особенности фактически не имеют отношения к принципам организации системного ПО, но сильно усложняют машинно-зависимую часть, например формирование двоичных команд в трансляторе с ассемблера. Поэтому мы будем использовать абстрактную учебную машину VM (Virtual Machine). Это позволит нам четко отделить теоретические аспекты и основные концепции от деталей реализации, связанные с архитектурой команд.
Примечание
В настоящее время абстрактную машину обычно называют виртуальной. Иногда используется термин «псевдомашина». Мы будем использовать эти термины как эквивалентные.
Эта книга не первая, в которой для изучения программирования используется абстрактная учебная машина. Например, Л.Бек в книге [_] по системному программированию использовал две разных учебных машины. Один из «гуру» программирования Никлаус Вирт в книге [_] при реализации компилятора для учебного языка тоже описал и использовал виртуальный компьютер. В другой своей книге о компиляторах [_] профессор Н.Вирт описывает виртуальный RISC-компьютер, в коды которого выполняется трансляция языка Оберон-0. В книге Свердлова С.З. [_] при описании процесса трансляции с языка высокого уровня тоже использована простая виртуальная машина. В книге [_] авторы учебного курса «Введение в компьютерные системы», преподаваемого более чем в 90 университетах мира, описывают архитектуру учебной виртуальной машины Y86. Однако самым знаменитым абстрактным компьютером является учебная машина MIX, которую описал Дональд Кнут в фундаментальном труде «Искусство программирования» [_].
Профессор Д.Кнут в настоящее время пишет четвертый и пятый том «Искусства программирования» (книга уже издается по частям). В связи с тем, что современные компьютеры довольно сильно отличаются от MIX, он разработал новую виртуальную машину MMIX (Modification MIX). В книге [_], где описана архитектура этого виртуального компьютера, профессор Д. Кнут написал:
MMIX — это RISC-компьютер, разработанный автором для иллюстрации программирования на машинном уровне. В следующих изданиях «Искусства программирования» MMIX заменит машину 60-х MIX.
Таким образом, при изучении системного программного обеспечения практически всегда используется разработанная автором книги абстрактная машина, и мы не будем отступать от этой традиции.
Виртуальные машины и промышленное программирование
Виртуальные машины находят широкое применение не только в обучении, но и в практике реального промышленного программирования. Одной из основных проблем в системном программировании является проблема переносимости (мобильности) программного обеспечения.
Программный продукт является переносимым (мобильным), если затраты на его перенос с одной архитектуры на другую много меньше, чем его реализация на новой архитектуре «с нуля».
Естественно, переносить имеет смысл только «многоразовое» ПО. Проблема мобильности программного обеспечения изучалась еще в 60-е годы прошлого столетия в основном на опыте переноса компиляторов. Именно в том время родилась идея использования абстрактной машины для облегчения переноса программ. Рассмотрим суть идеи. Пусть требуется реализовать N языков программирования на M различных архитектур. Очевидно, потребуется реализовать N*M компиляторов.
Пусть теперь определена подходящая виртуальная машина, и исходную программу можно транслировать в коды виртуальной машины. Тогда требуется разработать только N компиляторов, осуществляющих перевод исходной программы в коды виртуальной машины, и для каждого из М целевых компьютеров потребуется реализовать «исполнитель» команд виртуальной машины.
Такая схема имеет много преимуществ по сравнению с традиционной схемой реализации компиляторов без виртуальной машины.
Во-первых, использование виртуальной машины в значительной степени повышает переносимость: оттранслированная программа независима от исполняющей платформы и будет работать на любой ЭВМ, где реализован соответствующий исполнитель. С другой стороны, и компилятор, реализующий перевод исходной программы в коды виртуальной машины, становится менее зависимым от целевой платформы.
Во-вторых, налицо существенное сокращение объема работ: вместо N*M программ требуется только N+M программ. Поскольку виртуальную машину можно сделать настолько удобной, насколько возможно, — это обычно позволяет существенно уменьшить сложность реализации компилятора. Реализовать же исполнитель можно самыми разными способами:
- можно реализовать прямой интерпретатор, который и будет выполнять программы в кодах виртуальной машины на исполняющей машине;
- можно реализовать транслятор из кодов виртуальной машины в коды целевой машины (генератор кода);
- еще один способ – реализовать транслятор с ассемблера виртуальной машины в ассемблер исполняющего компьютера.
Преимуществом первого подхода является то, что интерпретатор можно сделать переносимым (например, реализовать его на стандартном С++). Другим важным преимуществом интерпретатора является то, что имеется возможность реализовать разные режимы работы, например, пошаговую трассировку команд с выводом результатов выполнения каждой команды в файл.
Обычно недостатком первого подхода называют низкую эффективность. Второй и подход обеспечивают выполнение программ со скоростью процессора целевой машины. Однако в этом случае мы лишаемся преимущества переносимости, поскольку транслятор в коды целевой машины очевидно машинно-зависим.
При сочетании первого и второго подхода получаем еще один вариант реализации исполнителя: JIT-компилятор.
Для реализации третьего подхода требуется разработка ассемблера виртуальной машины. Сам же транслятор можно реализовать несколькими способами: можно реализовать прямой транслятор; можно использовать макроассемблер целевой машины, определив для каждого оператора ассемблера виртуальной машины соответствующий макрос.
Таким образом, использование виртуальной машины обеспечивает беспрецедентную гибкость при разработке системного ПО.
Помимо этого абстрактная машина обеспечивает еще одно важнейшее свойство программ: совместимость. Поскольку все компиляторы транслируют в коды одной машины (виртуальной), появляется возможность разрабатывать отдельные компоненты большой системы на разных языках программирования. Компоновщик без особых проблем соберет их в одну программу.
При наличии стольких достоинств вызывает недоумение отсутствие повсеместного внедрения виртуальных машин в практику промышленного программирования. Тому есть несколько причин. Во-первых, до недавнего времени считалось, что применение абстрактных машин существенно снижает эффективность выполнения программ. В прежние времена это было справедливо, но в настоящее время производительность вычислительных систем настолько высока, что тезис о неэффективности в значительной мере утратил свою актуальность (тем не менее, существуют сферы применения ЭВМ, в которых эффективность важнее всех остальных характеристик). Во-вторых, не всякая программа может быть реализована как программа для виртуальной машины. Например, операционные системы по своей природе должны работать на реальной машине.