Лекции Баулы (1110628), страница 6
Текст из файла (страница 6)
<B+A2> := <R1> <B+A2>
Область, в которой находятся вычисляемые относительно базы ячейки основной памяти, обычно называется сегментом памяти – это сплошной участок памяти, начало которого задаётся в некотором регистре, называемом базовым, или сегментным. Будем далее для определённости называть такие регистры сегментными, а сам приём – сегментированием памяти.
Сегментирование позволяет резко уменьшить объём памяти для хранения программ, но оно имеет и один существенный недостаток: теперь каждая команда может обращаться не к любой ячейки оперативной памяти, а только к тем из них, до которых "дотягивается" смещение. В нашем примере каждая команда может обращаться к диапазону адресов от значения сегментного регистра B до B+212-1. Для доступа к другим ячейкам памяти необходимо записать в сегментный регистр новое значение (как говорят, перезагрузить сегментный регистр). Несмотря на указанный недостаток, практически все современные ЭВМ производят сегментирование памяти. Заметим также, что этот недостаток в большинстве архитектур современных ЭВМ исправляется путём реализации переменной длины смещения (например, разрешается смешение в 1, 2 или 4 байта), что, однако, ещё более увеличивает разнообразие языка команд.
Итак, для осуществления доступа к памяти ЭВМ необходимо, чтобы ячейка, к которой осуществляется доступ, находилась в сегменте, на начало которого указывает сегментный регистр. Современные ЭВМ обеспечивают одновременную работу с несколькими сегментами памяти и, соответственно, имеют несколько сегментных регистров.
В некоторых архитектурах регистры центрального процессора являются универсальными, т.е. каждый из них может быть использован как сегментный или для выполнения любых операций над данными. Сложность центрального процессора при этом существенно повышается, так что во многих архитектурах используются специализированные регистры, т.е. определённые регистры являются сегментными, на других могут производиться операции и т.д.
Ассемблер
Наличие большого количества форматов данных и команд в современных ЭВМ приводит к существенным трудностям при программировании на машинном языке. Для упрощения процесса написания программ для ЭВМ был разработан язык-посредник, названный Ассемблером, который, с одной стороны, должен быть машинно-ориентированным (допускать написание любых машинных программ), а с другой стороны – позволять автоматизировать процесс составления программ в машинном коде. Для перевода с языка Ассемблера на язык машины используется специальная программа-переводчик, также называемая Ассемблером (от английского слова “assembler” – “сборщик”). В зависимости от контекста, в разных случаях под словом "Ассемблер" будет пониматься или язык программирования, или программа-переводчик с этого языка на язык машины.
В нашем курсе мы не будем полностью изучать язык Ассемблера, для этого надо обязательно изучить соответствующие учебники [5-8]. Для целей изучения архитектуры ЭВМ нам понадобится только некоторое достаточно небольшое подмножество этого языка, только оно и будет рассматриваться на наших лекциях.
Функции программы-переводчика
Программа-переводчик должна как минимум уметь:
-
заменять мнемонические обозначения операций на соответствующие машинные коды операций (например, СЛН 087);
-
автоматически распределять память под хранения переменных, что позволяет программисту не заботиться о конкретном адресе переменной, если ему всё равно, где она будет расположена;
-
преобразовывать числа, написанные в программе в различных системах счисления во внутреннее машинное представление (в машинную систему счисления).
В конкретном Ассемблере обычно существуют много дополнительных возможностей для более удобного написания программ, однако при этом должны выполняться следующие требования (они вытекают из принципов Фон-Неймана):
-
возможность помещать в любое определённое программистом место памяти любую команду или любые данные;
-
возможность выполнять любые данные как команды и работать с командами, как с данными (например, складывать команды как числа).
Применение языка Ассемблера
Общеизвестно, что программировать на Ассемблере трудно. Как Вы знаете, сейчас существует много различных языков высокого уровня, которые позволяют затрачивать много меньше усилий при написании программ. Естественно, возникает вопрос, когда у программиста может появиться необходимость использовать Ассемблер при написании программ. В настоящее время можно указать две области, в которых использование языка Ассемблера оправдано, а зачастую и необходимо.
Во-первых, это так называемые машинно-зависимые системные программы, обычно они управляют различными устройствами компьютера (такие программы называются драйверами). В этих системных программах используются специальные машинные команды, которые нет необходимости применять в обычных (или, как говорят прикладных) программах.
Вторая область применения Ассемблера связана с оптимизацией выполнения программ. Очень часто программы-переводчики (компиляторы) с языков высокого уровня дают весьма неэффективную программу на машинном языке. Обычно это касается программ вычислительного характера, в которых большую часть времени выполняется очень небольшой (порядка 3-5%) участок программы (главный цикл). Если переписать этот участок программы на Ассемблере, то скорость работы программы может возрасти в несколько раз. Часто это единственный способ заставить программу дать результата за приемлемое время.
Понятие семейства ЭВМ
Компьютеры могут применяться в самых различных областях человеческой деятельности (эти области часто называются предметными областями). В качестве примеров можно привести область научно-технических расчётов (там много операций с вещественными числами), область экономических расчётов (там в основном операции над целыми числами и обработка символьной информации), мультимедийная область (обработка звука, изображения и т.д.), область управления различными сложными устройствами (ракетами, доменными печами и др.)
Компьютеры, архитектура которых ориентирована на какую-то одну предметную область, называются специализированными, в отличие от универсальных ЭВМ, которые более или менее успешно можно использовать во всех предметных областях. Мы в нашем курсе будем изучать архитектуру только универсальных ЭВМ.
Говорят, что компьютеры образуют семейство, если выполняются следующие требования:
-
одновременно выпускаются и используются несколько моделей семейства с различными производительностью и ценой (моделями называются компьютеры-члены семейства);
-
модели обладают программной совместимостью:
-
снизу-вверх – старшие модели поддерживают все команды младших (любая программа, написанная для младшей модели, безошибочно выполняется и на старшей);
-
сверху-вниз – на младших моделях выполняются программы, написанные для старших, если выполнены условия:
-
наличие у младшей модели достаточного количества ресурсов (например, памяти);
-
программа состоит только из поддерживаемых младшей моделью команд;
-
присутствует унификация устройств, то есть их аппаратная совместимость между моделями (например, печатающее устройство для младшей модели должно работать и на старшей);
-
модели организованы по принципу модульности, что позволяет в определённых пределах расширять возможности ЭВМ, увеличивая, например, объём памяти или повышая быстродействие центрального процессора;
-
стандартизировано системное программное обеспечение.
Большинство выпускаемых в наше время ЭВМ содержатся в каких-либо семействах. В нашем курсе для упрощения изложения будут рассматриваться в основном младшие модели семейства ЭВМ компании Intel. Соответственно все примеры программ должны выполняться для всех моделей этого семейства, поэтому мы ограничимся лишь архитектурой и системой команд самой младшей модели этого семейства [9].
Архитектура младшей модели семейства Intel
Память
Архитектура рассматриваемого компьютера является дробноадресной, поэтому адресуемая память состоит из регистровой и основной памяти. В младшей модели семейства основная память имеет объём 220 ячеек по 8 бит каждая.
Форматы данных
-
Целые числа.
Целые числа могут занимать 8 бит (короткое целое), 16 бит (длинное целое) и 32 бита (сверхдлинное целое). Длинное целое принято называть машинным словом (не путать с машинным словом в Учебной Машине!).
Как видим, в этой архитектуре есть многообразие форматов целых цисел, что позволяет писать более компактные программы. Для других архитектур это может оказаться несущественно, например, в некоторых современных супер-ЭВМ идёт работа с малым количеством целых чисел, поэтому вводится только один формат – сверхдлинное целое.
-
Символьные данные.
В качестве символов используются короткие целые числа, которые трактуются как неотрицательные (беззнаковые) числа, задающие номер символа в некотором алфавите. Заметим, что как таковой символьный тип данных (в смысле Паскаля) в Ассемблере отсутствует, а запись 'A' обозначает не символьный тип данных, а эквивалентна выражению языка Паскаль Ord('A').
-
Массивы (строки).
Массивы могут состоять из коротких или длинных целых чисел. Массив коротких целых чисел может рассматриваться как символьная строка. В машинном языке присутствуют команды для обработки элементов таких массивов, если такую команду поставить в цикл, то образуются удобное средство для работы с массивами.
-
Вещественные числа.
Чаще всего используются три формата вещественных чисел: короткие, длинные и сверхдлинные вещественные. Стоит отметить следующий важный факт. Если целые числа в различных ЭВМ по чисто историческим причинам имеют разное внутреннее представление, то на момент появления вещественных чисел уже существовал определённый стандарт и почти все современные машины этого стандарта придерживаются.
Рассмотрим представление короткого вещественного числа в этом стандарте
| E | M |
1 бит | 8 бит | 23 бита |
В отличие от целых, в представлении вещественных чисел используется симметричная числовая ось, то есть для любого положительного числа найдётся соответствующее ему отрицательное, и наоборот. Первый бит числа определяет его знак (знак «плюс» кодируется нулём, «минус» – единицей).
Остальная биты, отведённые под хранение вещественного числа, разбивается на две части: машинный порядок E и мантиссу M, которая по модулю меньше единицы. Каждое представимое вещественное число A (кроме числа 0.0) может быть записано в виде: A=1.M*2E–127. Такие вещественные числа называются нормализованными: первый сомножитель удовлетворяет неравенству 1.0 1.M < 2.0. Нулевое число представляется нулями во всех позициях, за исключением, быть может, первой.
Таков формат короткого вещественного числа. Согласно его виду, E изменяется от 0 до 255, следовательно диапазон порядков коротких вещественных чисел равен 2–127..2128 10–38..1038. Как и для целых чисел, машинное представление которых мы рассмотрим чуть позже, число представимых вещественных чисел конечно.
Некоторые комбинации нулей и единиц в памяти, отведённой под вещественное число, собственно числа не задают, а используются для служебных целей. В частности, E=255 обозначает специальное значение "не число" (not a number). При попытке производить арифметические операции над такими числами возникает аварийная ситуация. Например, значение "не число" может быть присвоено вещественной переменной при её порождении, если эта переменная не имеет начального значения (как говорят, не инициализирована). Такой приём позволяет избежать тяжёлых семантических ошибок, которые могут возникать при работе с неинициализированными переменными.
Отметим ещё две специальные комбинации нулей и единиц, которые будем обозначать . Эти значения присваиваются результату операции с вещественными числами, если этот результат не равен нулю, не непредставим в виде вещественного числа, то есть меньше самого маленького представимого положительного вещественного числа и больше самого большого отрицательного.
Аналогично существуют комбинации битов, задающие специальные значения . Эти значения выдаются в качестве результата, если этот результат такой болькой по абсолютной величине, что непредставим среди множества машинных вещественных чисел.
Центральный процессор "разумно" (по крайней мере с точки зрения математика) производит арифметические операции над такими "числами". Например, пусть A любое представимое вещественное число, тогда